c - 使用 __attribute__((packed)) 在 c 中避免结构填充

标签 c struct

我正在使用 __attribute__((packed)) 来避免结构填充。下面的代码工作正常,但是当我在结构中再添加一个 int 成员时,编译器会填充我的结构。

#include <stdio.h>

struct test {

    int x;
    char c1;
    char c2;
    char c3;
    char c4;
    char c5;
    // int d; Pads if I uncomment

} __attribute__((packed)) obj = {50,'X','Y','Z','A','B'}; 

int main ()
{
    struct test *ptr= &obj;
    char *ind = (char *) &obj;

    printf("\nLet's see what is the address of obj %d", ptr);
    printf("\n Size of obj is : %d bytes ", sizeof(obj));
    printf("\nAddress of x is %d", &ptr->x);
    printf("\nAddress of c1 is %d", &ptr->c1);
    printf("\nAddress of c2 is %d", &ptr->c2);
    printf("\nValue  of x is %d", ptr->x);
    printf("\nAddress of x is %c", ptr->c1);
    printf("\nFetching value of c4 through offset %c", *(ind+7));

}

上面的代码按预期工作,obj 的大小为 9 个字节(填充后为 12 个字节)。

但是,当我在我的结构中取消注释 int d 时,代码输出:

Size of obj is : 16 bytes

而不是预期的 13 (9 + 4) 字节。

怎么了?

最佳答案

在结构中有两种类型的填充。 (1) 添加填充以使结构成为某个数字的倍数(在您的情况下为 int 的大小)和 (2) 添加填充以将某些数据类型定位在可被特定数字整除的地址处。例如,int 为 4 个字节。因此,在您的情况下,虽然编译器很乐意删除第一种类型的填充,但我认为它仍在强制成员 int d 到可被 4 整除的地址。因为 d< 之前有 5 个字符,添加 3 个字节填充以强制 d 为可被 4 整除的地址。

所以尝试将成员 int d 移到字符之上。那么当然你必须更改通过偏移量获取c4的值中使用的偏移量。您甚至可以将它放在 c5 的正上方。那么您就不必更改 fetching value of c4 through offset 行。示例:

struct test {

    int x;
    int d;
    char c1;
    char c2;
    char c3;
    char c4;
    char c5;

} __attribute__((packed)) obj = {50,'X','Y','Z','A','B'}; 

struct test {

    int x;
    char c1;
    char c2;
    char c3;
    char c4;
    int d;
    char c5;

} __attribute__((packed)) obj = {50,'X','Y','Z','A','B'}; 

关于c - 使用 __attribute__((packed)) 在 c 中避免结构填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32014137/

相关文章:

c - 有没有数组除了sizeof没有转成指针的情况?

c++ - 为什么系统调用 socket(AF_INET, SOCK_RAW, IPPROTO_RAW) 返回 -1 的文件描述符?我认为这是一个错误

arrays - Swift 中数组和结构的运行时错误

json - 如何从另一个平面/简单的配置单元表中使用 map[structs] 加载配置单元表

swift - "public private(set)"访问修饰符如何工作?

c - fopen 的文件字符串错误?

c - 移动 n 位的 __m128i

c++ - 结构前向声明错误 : Typedef redefinition with different types

c - 如何在 C 中打印 IP 地址的点分小数部分的特定值?

c - 在c中合并和排序结构数组