我想知道下面这个程序的行为,因为填充是基于 C 编程中的相邻数据类型。
#include <stdio.h>
struct abc{
char a1;
int a2;
}X;
struct efg
{
char b1;
double b2;
}Y;
int main()
{
printf("Size of X = %d\n",sizeof(X));
printf("Size of Y = %d\n",sizeof(Y));
return 0;
}
程序的输出
root@root:~$./mem
Size of X = 8
Size of Y = 16
在结构abc中填充了3个字节,而在结构efg中填充了7个字节。
padding 是这样设计的吗?
最佳答案
正在添加填充以避免成员在不需要时跨越单词边界;对齐,正如一些人在评论中所说的那样。这里有一个很好的解释:
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/structure-packing有关结构排序/打包的更多详细信息...
关于c - 为什么填充基于数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43834735/