柔性数组: 结构体的最后一个成员允许是一个未知大小的数组,这个数组就叫做柔性数组
目录
1、柔性数组的声明
声明方式的两种如下:
struct Person
{
int age;
char address[];
//char address[0] // 如果编译器会报错,就改成上面这种
};
既然结构体最后一个成员可以是未知大小的数组,那么柔性数组的前面至少要有一个成员。
2、柔性数组所在结构体的大小
在计算包含柔性数组的结构体大小的时候,sizeof 返回的这种结构大小不包括柔性数组的内存
也就是说,上述的结果仅仅只是计算了 i 所占空间的大小,在计算其他成员的大小时,依然需要满足内存对齐原则。
3、柔性数组所在结构体的初始化
如果结构体里包含了柔性数组,那就无法使用普通方法初始化,因为在分配空间的时候,因为不知道最后一个成员要占用多大空间,因此需要我们手动分配空间。
int main() {
struct Person* p = (struct Person*)malloc(sizeof(struct Person) + sizeof(char) * 10);
p->age = 10;
for (size_t i = 0; i < 10; i++)
{
p->address[i] = 0;
}
return 0;
}
这也是柔性数组的最后一个特点:柔性数组所在结构体需使用 malloc 进行动态内存分配,分配的大小必须大于结构体的大小
4、柔性数组的优势
(1) 方便内存释放
柔性数组需要通过 malloc 来初始化。如果你先给结构体初始化,然后再给结构体里的数组初始化,那就像下面这样。
int main() {
struct Person* p = (struct Person*)malloc(sizeof(struct Person));
p->age = 10;
p->address = (char*)malloc(sizeof(char) * 10);
free(p->address);
p->address = NULL;
free(p);
p = NULL;
return 0;
}
这个时候需要分配两次空间,你需要先释放里面的数组,再释放整个结构体。
(2) 减少内存碎片,提高空间利用率和访问速度
我们每malloc一次,内存就会给我们分配一块空间。但是空间与空间之间,会需要通过一小段字节隔开,malloc次数越多,空间碎片也就越多。
此时的空间利用率就很低,结构体里的其他成员和柔性数组明明同属于一个结构体,访问的时候却无法连续访问。