#P9754. [CSP-S 2023] 结构体
[CSP-S 2023] 结构体
Background
In high-level languages such as C++, besides basic types like int and float, you can usually define your own struct types. In this problem, you need to simulate a struct definition method similar to that of a C++-like high-level language, and compute the corresponding memory usage and related information.
Problem Description
In this language, there are basic types: byte, short, int, long, which occupy , , , bytes of memory, respectively.
When defining a struct type, you need to provide the type name and its members. Each member must be given, in order, with its type and name. A type can be a basic type or a struct type that has been defined earlier. Note that defining a struct type does not define any concrete variable, so it does not occupy memory.
When defining an object (an instance/variable), you need to provide the object’s type and name. Objects occupy memory according to the following rules:
- All members inside an object are laid out in memory in the same order as in the definition. The same applies to members whose type is a struct.
- To ensure efficient memory access, the object’s address allocation must satisfy the alignment rules: for any type, both the size of the type and the starting address of an object of that type in memory must be aligned to an integer multiple of the type’s alignment requirement. Specifically:
- For basic types: the alignment requirement equals the size it occupies. For example,
intmust be aligned to bytes, and similarly for the others. - For struct types: the alignment requirement equals the maximum alignment requirement among its members. For example, a struct type containing
intandshortmust be aligned to bytes.
- For basic types: the alignment requirement equals the size it occupies. For example,
Here is an example (written in C++ format):
struct d {
short a;
int b;
short c;
};
d e;
This code defines the struct type d and an object e. Object e contains three members e.a, e.b, e.c, occupying address ranges , , and , respectively. Since type d needs to be aligned to bytes, e occupies addresses , with a total size of bytes.
You need to process operations. Each operation is one of the following four types:
-
Define a struct type. Specifically, you are given a positive integer and strings , where is the number of members, is the type name, are the member types in order, and are the member names in order. You need to output the size and alignment requirement of this struct type, separated by a space.
-
Define an object. Specifically, you are given strings , representing the object’s type and name. All defined objects are placed in order in memory starting from address , and must satisfy the address alignment rules. You need to output the starting address of the newly defined object.
-
Access an object. Specifically, you are given a string representing the object to be accessed. As in C++ and similar languages,
.is used to access members of a struct type. For example,a.b.cmeansais a defined object; it is a struct type and has a member namedb, which is also a struct type and has a member namedc. You need to output the starting address of the innermost element accessed as above. -
Access a memory address. Specifically, you are given a non-negative integer , representing the address to access. You need to determine whether there exists a basic-type element that occupies this address. If yes, output that element in the same access format as in operation 3; otherwise output
ERR.
Input Format
Line : a positive integer , the number of operations.
The following lines describe the operations in order. The first integer on each line is , the operation type:
-
If , first input a string and a positive integer , representing the type name and number of members. Then follow lines, each containing two strings , representing the type and name of each member in order.
-
If , input two strings , representing the type and name of the object.
-
If , input one string , representing the object to be accessed.
-
If , input one non-negative integer , representing the address to be accessed.
Output Format
Output lines, in order, each being the result of the corresponding operation, as required in the statement.
5
1 a 2
short aa
int ab
1 b 2
a ba
long bb
2 b x
3 x.ba.ab
4 10
8 4
16 8
0
4
x.bb
Hint
Sample 1 Explanation
In struct type a, the short member aa occupies addresses , and the int member ab occupies addresses . Since its alignment requirement is bytes, its size is bytes. Similarly, the size of struct type b is bytes, and its alignment requirement is bytes.
Sample 2
See struct/struct2.in and struct/struct2.ans in the contestant directory.
Sample 2 Explanation
In the second operation 4, the accessed memory address lies exactly in a “hole” left for address alignment, so no basic-type element occupies it.
Sample 3
See struct/struct3.in and struct/struct3.ans in the contestant directory.
Constraints
For all data, , , .
All defined struct type names, member names, and object names consist of at most lowercase letters, and none of them is byte,short,int,long (i.e., they do not share a name with any basic type).
All defined struct type names and object names are pairwise distinct, and member names within the same struct are pairwise distinct. However, different structs may have the same member name, and a member name within some struct may also be the same as a defined struct or object name.
It is guaranteed that all operations follow the rules and requirements described in the statement. In particular, struct definitions will not include nonexistent types, and accesses will not refer to nonexistent objects or members.
It is guaranteed that the size of any struct and the maximum memory address occupied by defined objects do not exceed .
| Test Point | Special Property |
|---|---|
| A, D | |
| A | |
| B, D | |
| B | |
| C, D | |
| C | |
| D | |
| None |
Special property A: there is no operation .
Special property B: there is only one operation .
Special property C: in all operations , all member types are basic types.
Special property D: the only basic type is long.
Hint
The formal definitions of the alignment requirement and size of a struct type are as follows:
- Suppose the struct has members, with sizes and alignment requirements .
- Then the alignment requirement of this struct is .
- Let the address offsets of these members in the layout be . Then:
- .
- For , is the smallest value such that and divides .
- The size of this struct is the smallest value such that and divides .
The formal definition of the memory layout when defining objects is as follows:
- Suppose the -th defined object has size , alignment requirement , and starting address .
- Then . For , is the smallest value such that and divides .
Translated by ChatGPT 5