问:如下代码,两个结构体类型成员变量相同,只是成员顺序不同,为什么大小不同?
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>typedef struct _test1{uint8_t a;uint32_t b;uint8_t c;
}test1_t;typedef struct _test2{uint8_t a;uint8_t c;uint32_t b;
}test2_t;int main(int argc, char* argv[])
{printf("sizeof(test1_t): %ld\r\nsizeof(test2_t): %ld\r\n", sizeof(test1_t), sizeof(test2_t));return 0;
}
运行输出:
sizeof(test1_t): 12
sizeof(test2_t): 8
答:变量默认遵循如下对齐规则:一字节的变量不做要求,两字节的变量至少要两字节对齐,四字节变量至少是四字节对齐。什么是字节对齐呢?以四字节对齐为例,就是变量的首地址要是4的倍数。结构体成员变量也要遵守如上的对齐规则,此外结构体的首地址要按最大成员变量对齐,结构体的大小必须是最大成员变量的整数倍。
test1_t类型的结构体它的最大成员变量b是4字节,该结构体一定是4字节对齐的,也就是第一个成员变量a是4字节对齐,第二个变量b也必须是4字节对齐,a和b之间会有3个字节的空隙,c大小是1字节,紧跟在b之后即可,但是test1_t的大小一定是4的倍数,所以c的后面也会有3字节的空隙。总的大小是12字节。
同样的方法分析test2_t类型的结构体,a占1字节,b占1字节,b和c之间有2字节的空隙,c占4字节,总大小8字节。
问:这样结构体成员之间会有空隙浪费空间,有没有办法让各成员紧密排列不留空隙?
答:可用__attribute__((packed))指定结构体成员之间紧密排列,而不按默认对齐方式预留空隙。代码如下:
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>typedef struct _test1{uint8_t a;uint32_t b;uint8_t c;
} __attribute__((packed)) test1_t ;typedef struct _test2{uint8_t a;uint8_t c;uint32_t b;
}__attribute__((packed)) test2_t;int main(int argc, char* argv[])
{printf("sizeof(test1_t): %ld\r\nsizeof(test2_t): %ld\r\n", sizeof(test1_t), sizeof(test2_t));return 0;
}
运行输出:
sizeof(test1_t): 6
sizeof(test2_t): 6