何为柔性数组
struct node {
int x, y;
int arr[0];
};
int main() {
printf("%d\n", sizeof(node));
}
输出
8
我们可以在结构体的末尾放入一个长度为 0 的数组(注:如果不是末尾,编码器则会报错),从输出结果可以看到这个长度为 0 的数组没有占用空间。
柔性数组是引入的一个新特性,允许在定义结构体时,最后一个成员为一个空数组,并且这样的结构体至少包含一个其他类型的成员。这样,此结构体是可变长的。
柔性数组的好处
我们将柔性数组与字符串指针两种方式作比较。
柔性数组的使用:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Node {
int n;
char arr[0];
};
int main() {
struct Node* node = (struct Node*)malloc(sizeof(struct Node) + 11 * sizeof(char));
if (node == NULL) {
perror("malloc error");
return 1;
}
node->n = 11;
memcpy(node->arr, "hello world", 11);
printf("%d, %s\n", node->n, node->arr);
free(node);
node = NULL;
return 0;
}
而使用字符串指针是这样的:
struct Node {
int n;
char* arr;
};
int main() {
struct Node* node = (struct Node*)malloc(sizeof(struct Node));
if (node == NULL) {
perror("malloc");
return 1;
}
node->n = 11;
node->arr = (char*)malloc(sizeof(char) * 11);
if (node->arr == NULL) {
perror("malloc node->arr");
return 1;
}
memcpy(node->arr, "hello world", 11);
printf("%d, %s\n", node->n, node->arr);
free(node->arr);
node = NULL;
free(node);
return 0;
}
可以看出它们空间分配的差别:使用字符串指针的方式,需先为 Node 结构体分配一块内存空间,再为 Node 的 arr 变量分配内存空间,这样两次分配的内存是不连续的;而使用 0 数组时,一次分配就行了。在释放时使用字符串指针的方式也需要多次释放,使用 0 数组一次释放就行了。
另外,第二种方式的结构体的大小为 16,其中 n 为 4,char* 为 8,经内存对齐后为 16。而零数组所在的结构体大小为 4。
所以,我们可以总结下零数组的好处有:
- 有利于提高访问速度。访问数组内容时,不需要像字符串指针一样间接访问,避免了两次访存;
- 方便内存的释放。只需要使用一次 free 函数去释放结构体指针;
- 减少了指针占用的空间