我想知道以下程序的行为,因为填充基于C编程中的相邻数据类型。
#include <stdio.h>
struct abc{
char a1;
int a2;
}X;
struct efg
{
char b1;
double b2;
}Y;
int main()
{
printf("Size of X = %dn",sizeof(X));
printf("Size of Y = %dn",sizeof(Y));
return 0;
}
程序的输出
root@root:~$./mem
Size of X = 8
Size of Y = 16
在结构中,ABC 3字节是填充的,而在结构EFG 7字节中则是填充。
这是如何设计的?
正在添加填充,以避免成员在不需要时越过单词边界;正如某些人在评论中所说的那样。这里有一个很好的解释:
http://www.geeksforgeeks.org/structure-member-alignment-padding-and-data-packing/
最大成员的大小确实会影响其他成员的填充。通常,所有成员都与最大成员的规模保持一致。我相信这是因为这只是编译器确保所有结构成员都正确对齐的最简单/最有效的方法。
因此,一个有趣的细节是,如果您按大小订购结构成员,则通常可以节省空间,最大的成员首先声明。这里有一些代码来说明(我总是发现查看实际内存的转储有助于处理此类内容,而不仅仅是大小(
#include <stdio.h>
// Inefficient ordering-- to avoid members unnecessarily crossing word
// boundaries, extra padding is inserted.
struct X {
unsigned long a; // 8 bytes
unsigned char b; // 4 bytes
unsigned int c; // 4 bytes
unsigned char d; // 4 bytes
};
// By ordering the struct this way, we use the space more
// efficiently. The last two bytes can get packed into a single word.
struct Y {
unsigned long a; // 8 bytes
unsigned int c; // 4 bytes
unsigned char b; // 1 byte
unsigned char d; // 3 bytes
};
struct X x = {.a = 1, .b = 2, .c = 3, .d = 4};
struct Y y = {.a = 1, .b = 2, .c = 3, .d = 4};
// Print out the data at some memory location, in hex
void print_mem (void *ptr, unsigned int num)
{
int i;
unsigned char *bptr = (unsigned char *)ptr;
for (i = 0; i < num; ++i) {
printf("%.2X ", bptr[i]);
}
printf("n");
}
int main (void)
{
print_mem(&x, sizeof(struct X)); // This one will be larger
print_mem(&y, sizeof(struct Y)); // This one will be smaller
return 0;
}
和运行上述代码的输出:
01 00 00 00 00 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 00 00 00 00
01 00 00 00 00 00 00 00 03 00 00 00 02 04 00 00
这有多种微妙之处,我敢肯定它在各种实现方面的工作方式有所不同。请参阅http://www.catb.org/esr/sstructure-packing,以获取有关结构订购/包装的更多信息详细信息...