我正在使用 __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/