c - 为什么填充基于数据类型

标签 c

我想知道下面这个程序的行为,因为填充是基于 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/

相关文章:

c - 枚举中的值是多少?

c - 对未初始化变量有任何保证吗?

c - 将文件写入内存缓冲区(fopen something,但写入缓冲区,而不是磁盘)

检查三元运算符是否存在的 C 程序

c - 在我的 windows(xp) PC 中,哪里可以看到 malloc() 或任何库函数的源代码?

c - 如何将gets()代码更改为fgets()?

c - C中void和float函数的区别

c++ - C/C++ 项目可以使用 Xcode 编译,但不能使用 gcc/g++ 编译

c - 使用 Visual Studio 2008/Visual C++ 2008 Express 学习 C

c++ - 抛出错误 "as ‘p’ 中的包装函数未在此范围内声明”