我理解C中的结构概念.我也理解结构如何存储在内存中.所以我创造了以下内容:
struct tag1 {
char a;
int b;
}var1;
Run Code Online (Sandbox Code Playgroud)
结构的大小是8个字节(以gcc为单位).
内存布局示例.
-----------
| | | | | ---> char a (only 1 byte is used and remaining 3 bytes are padding)
-----------
| | | | | ---> int b (4 byte is used)
-----------
Run Code Online (Sandbox Code Playgroud)
现在我对这个示例程序有一些疑问.嵌套结构如何存储在内存中.
struct tag1{
int a;
struct tag2{
long b;
}var1;
}var2;
Run Code Online (Sandbox Code Playgroud)
如注释中所述,内存中结构的确切布局是特定于实现的.通常也是如此,布局受成员类型,内存寻址(32位或64位)以及pragma pack调整沿内存边界对齐方式的调用的影响.
一个例子是什么我在我的系统上看到的,当我把你原来的结构作为子结构成员的两个实例到另一个结构(上下文,并迫使连续内存分配),然后赋值给结构的实例提供内存布局中可区分(非零)的内容:
(32位寻址,没有编译指示)
typedef struct tag1{
int a;
struct tag2{
long b;
}var1;
}var2;
typedef struct {
var2 s1;
var2 s2;
}S;
Run Code Online (Sandbox Code Playgroud)
主要:
S x = {0};
x.s1.a = 1;
x.s1.var1.b = 2;
x.s2.a = 3;
x.s2.var1.b = 4;
Run Code Online (Sandbox Code Playgroud)
struct S在第一行图像上描绘的内存:
请注意,由于struct或甚至是子结构构造,不需要直接使用额外的内存.但间接地,对齐填充可能需要(通常会有)额外的内存.当结构定义中包含的数据类型具有不同的大小并且不会沿着寻址边界自然对齐时,会发生这种情况.发生这种情况时,填充将影响计算sizeofa struct.
你可以看到你的原始结构的每个实例的大小为8,(16两个实例),也因为int与long这两个在这种情况下完全一致(和大小都一样),似乎没有填充.如果long被替换为long long这将不再是这种情况.几乎肯定需要填充.
为了提供以下信息的上下文,我的机器上的相关数据大小(编译为32位)是:
int sizeChar = sizeof(char); //1 (always)
int sizeInt = sizeof(int); //4
int sizeLong = sizeof(long); //4
int sizeLL = sizeof(long long);//8
Run Code Online (Sandbox Code Playgroud)
将有更明显的填充证据和使用更广泛类型的pragma的影响.以下结构包含4种数据类型:
typedef struct tag1 {
char a;
int b;
long c;
long long d;
}var1;
Run Code Online (Sandbox Code Playgroud)
使用此结构定义,有趣的是查看使用pragma pack调用导致的填充的差异.在我的机器上,并编译32位内存映射,这是我看到的:
顺便说一句,有一个讨论,这里本主题涵盖相关穴位.