目录
有关柔性数组开辟相关的malloc函数博文:
C语言动态内存管理(malloc, calloc,realloc)详解-CSDN博客
结构体以及其大小的计算:
结构体、枚举以及联合类型在内存中的存储与大小计算-CSDN博客
柔性数组也称为变长数组,是一种动态数组的实现方式。
与普通数组不同的是,柔性数组在定义时不需要明确指定数组大小,在程序运行时可以动态地分配和扩展数组大小。
柔性数组是通过C99标准中提供的“结构体成员为未知长度的数组”的特性来实现的,它需要一个结构体来作为数组的容器,并且在结构体定义中,最后一个数组成员不指定长度,例如:
- struct S
- {
- char c;
- int i;
- int arr[0];//未知大小的数组 - 柔性数组成员
- };
同一种写法:
上面的一种写法有的编译器会报错
- struct S
- {
- char c;
- int i;
- int arr[];//未知大小的数组 - 柔性数组成员
- };
例如我们把上诉结构体的大小计算一下
- struct S
- {
- char c;
- int i;
- int arr[];//未知大小的数组 - 柔性数组成员
- };
- int main()
- {
- printf("%d\n", sizeof(struct S));
- return 0;
- }
运行结果:

使用柔性数组时,我们需要手动分配内存空间,并且调整数组的大小。例如,可以使用malloc函数分配内存空间,并根据实际需要调整数组的大小:
- struct S
- {
- char c;
- int i;
- int arr[];//未知大小的数组 - 柔性数组成员
- };
- int main()
- {
- struct S* ps = (struct S*)malloc(sizeof(struct S) + 20);
- if (ps == NULL)
- {
- perror("malloc");
- return 1;
- }
- int i = 0;
- ps->i = 100;
- for (i = 0; i < 100; i++)
- {
- ps->arr[i] = i;
- }
- for (i = 0; i < 100; i++)
- {
- printf("%d ", ps->arr[i]);
- }
- free(ps);
- ps = NULL;
- return 0;
- }
运行结果:

我们来看下面两段代码,其设计是一样的
- struct S
- {
- char c;
- int i;
- int* data;
- };
-
-
- int main()
- {
- struct S* ps = (struct S*)malloc(sizeof(struct S));
- if (ps == NULL)
- {
- perror("malloc1");
- return 1;
- }
- ps->c = 'w';
- ps->i = 100;
- ps->data = (int*)malloc(20);
- if (ps->data == NULL)
- {
- perror("malloc2");
- return 1;
- }
- int i = 0;
- for (i = 0; i < 5; i++)
- {
- ps->data[i] = i;
- }
- for (i = 0; i < 5; i++)
- {
- printf("%d ", ps->data[i]);
- }
- //空间不够了,增容
- int* ptr = (int*)realloc(ps->data, 40);
- if (ptr == NULL)
- {
- perror("realloc");
- return 1;
- }
- else
- {
- ps->data = ptr;
- }
- //增容成功就使用
- //...
- //释放
- free(ps->data);
- ps->data = NULL;
- free(ps);
- ps = NULL;
-
- return 0;
- }
我们在使用malloc给柔性数组开辟内存时,使用完后是需要释放内存的,我们来看它们在内存中的存放

这种开辟的内存空间并不是紧挨着后面开的,而是随便找的一块内存空间,这就导致我们需要多次释放内存。
而柔性数组是紧挨着结构体后开辟的空间,可以直接一次性的释放
- struct S
- {
- char c;//1
- //3
- int i;//4
- int arr[];//未知大小的数组 - 柔性数组成员
- };
-
- int main()
- {
- struct S* ps = (struct S*)malloc(sizeof(struct S) + 20);
- if (ps == NULL)
- {
- perror("malloc");
- return 1;
- }
- ps->c = 'w';
- ps->i = 100;
- int i = 0;
- for (i = 0; i < 5; i++)
- {
- ps->arr[i] = i;
- }
- //打印
- for (i = 0; i < 5; i++)
- {
- printf("%d ", ps->arr[i]);
- }
- //空间不够了
- struct S* ptr = (struct S*)realloc(ps, sizeof(struct S)+40);
- if (ptr != NULL)
- {
- ps = ptr;
- }
- else
- {
- perror("realloc");
- return 1;
- }
- //增容成功后,继续使用
-
- //释放
- free(ps);
- ps = NULL;
-
- return 0;
- }
因为有时内存的开辟不是紧挨着的,而是一块一块的,这就造成了一些内存的浪费,所以有时像柔性数组这样紧挨着开辟的是很有必要的。
