我正在编写一个程序来解压缩PE文件。我有一个结构,Pe_SymbolHeader。看起来是这样的:
typedef struct _Pe_SymbolHeader {
char Name[8]; // 8
uint32_t Value; // 12
uint16_t SectionNumber; // 14
uint16_t Type; // 16
uint8_t StorageClass; // 17
uint8_t NumberOfAuxSymbols; // 18
} Pe_SymbolHeader;gcc告诉我这个结构的大小是20个字节。
printf("sizeof Pe_SymbolHeader %d\n", sizeof(Pe_SymbolHeader));我决定在堆栈上放置一个Pe_SymbolHeader,并查看内存中的所有内容。
Pe_SymbolHeader test
printf("%p\n", &(test.Name));
printf("%p\n", &(test.Value));
printf("%p\n", &(test.SectionNumber));
printf("%p\n", &(test.Type));
printf("%p\n", &(test.StorageClass));
printf("%p\n", &(test.NumberOfAuxSymbols));这给了我以下几点,这似乎是可以的:
0x7fffffffe150
0x7fffffffe158
0x7fffffffe15c
0x7fffffffe15e
0x7fffffffe160
0x7fffffffe161那么,如果gcc用18个字节来存储我的结构,为什么要告诉我这个结构需要20个字节呢?
编辑:好吧,gcc试图帮助我的方式似乎是要我的命,有几个答案是正确的。我只能投一票,但是谢谢你的回答。。
发布于 2011-10-02 21:13:50
因为衬垫对齐
结构的末尾有填充物。
原因与数组中发生的事情有关,也可能与结构后面的其他上下文有关。某种东西可能是这个结构的另一个实例。该结构包含一个32位对象,因此它将有32位的对齐要求。
编译器非常希望下一项从它正在编译的体系结构的自然单词边界开始,这样下一个对象中的任何字段都可以用一个操作来读取,而不是使用两个操作,再加上一些摆弄来组合两个不同的“单词”。
发布于 2011-10-02 21:12:21
结构的uint32_t部分需要在4个字节的倍数上对齐,因此结构的大小必须是4个字节的倍数,以确保结构的数组不会造成麻烦(错误对齐访问问题--这会导致某些机器上的SIGBUS错误和(大多数)其他机器上(非常)低效的访问)。因此,编译器要求结构末尾有2个填充字节;这些字节没有名称,因此不能合法地访问它们。
发布于 2011-10-02 21:11:56
,所以如果gcc用18个字节来存储我的结构,为什么要告诉我这个结构需要20个字节呢?
将像这样的2个结构体放在堆栈上,并为它们打印相同的东西,这将启发您。
https://stackoverflow.com/questions/7629231
复制相似问题