一、结构体对齐
? 结构体是C语言中的一种自定义类型,结构体中可以有不同类型的数据类型作为结构体的成员,其中,这些成员在内存中存储的时候,存在内存对齐现象。
🍖1、什么是内存对齐?
? 那么问题来了?什么是结构体的内存对齐呢? 结构体内存对齐其实是,结构体成员在内存中的存储情况,结构体内存对齐规则如下: ? 第一个成员在与结构体变量偏移量为0的地址处。
?其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
?结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
?如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍
🍖2、计算结构体大小示例
让我们先通过几个小例子看一下👉
?例1:
struct S1
{
char c1;
int i;
char c2;
};
printf("%d\n", sizeof(struct S1));
?按照常理,我们会认为char占一个字节,int占4个字节,整个结构体S1占6个字节就可以了,但是真的如我们想的这样吗?看下面分析:👉👉
?例2:
struct S2
{
char c1;
char c2;
int i;
};
printf("%d\n", sizeof(struct S2));
?例3:
struct S3
{
double d;
char c;
int i;
};
printf("%d\n", sizeof(struct S3));
👀 上边三个例子的结构体中各有三个成员,让我们来看看最终运行结果,是不是和我们分析的一样呢😁😁😁
正如我们分析的那样结果为12,8,16😀😀😀
🍖3、默认对齐数
💬 VS默认对齐数为8,gcc没有指定默认对齐数,问题又来了,默认对齐数能不能修改呢?如何进行修改?
看下边命令:💋
#pragma pack(8)
#pragma pack()
二、柔性数组
🍖1、什么是柔性数组
?C99 中,结构中的最后一个元素允许是未知大小的数组,这就叫做『柔性数组』成员。
它长这样 👉
typedef struct st_type
{
int i;
int a[0];
}type_a;
或者 👉
typedef struct st_type
{
int i;
int a[];
}type_a;
- 结构中的柔性数组成员前面必须至少一个其他成员。
- sizeof 返回的这种结构大小不包括柔性数组的内存。
- 包含柔性数组成员的结构用malloc ()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。
🍖2、怎么使用柔性数组
?我们可以看到呀,结构体中有个未指定大小的数组,我们该如何使用它呢? 答案就是动态内存分配,需要用该方法指定柔性数组的大小。
例如 👉
typedef struct st_type
{
int i;
int a[];
}type_a;
int main()
{
type_a *p = (type_a*)malloc(sizeof(type_a)+100*sizeof(int));
return 0;
}
这样可以开辟100个整型空间大小的柔性数组,柔性数组也是有它的好处的:
|