我__attribute__((packed))用来避免struct padding.下面的代码工作正常,但是当我int在struct中添加一个更多的成员时,编译器会填充我的struct.
#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));
}
Run Code Online (Sandbox Code Playgroud)
上面的代码按预期工作,大小obj为9个字节(填充为12个字节).
但是,当我int d在我的结构中取消注释时,代码输出:
obj的大小是:16个字节
而不是预期的13(9 + 4)字节.
怎么了?
在结构中涉及两种类型的填充。(1) 添加填充以使结构成为某个数字的倍数(在您的情况下为 的大小int)和 (2) 添加填充以将某些数据类型放置在可被某个数字整除的地址处。例如,4 个字节int。因此,在您的情况下,虽然编译器很乐意删除第一种填充类型,但我认为它仍然强制成员int d到可被 4 整除的地址。由于之前有 5 个字符d,因此添加 3 个字节填充以强制d到可被 4 整除的地址。
因此,请尝试将成员移动int d到字符上方。那么当然你必须改变 中使用的偏移量fetching value of c4 through offset。您甚至可以将其放在正上方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'};
Run Code Online (Sandbox Code Playgroud)
或者
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'};
Run Code Online (Sandbox Code Playgroud)