柔性数组是一种可变大小的数组,即他可以在你使用的时候根据你的需要变大或者变小,在C99标准下支持这样一种语法。
但是使用柔性数组有一定的条件限制。
1,柔性数组必须包含在结构体内,且必须是结构体的最后一个成员。
2,柔性数组成员前,至少存在一个其他成员。
3,数组的大小未定义或者定义为0(arr[ ]或者arr[ 0 ],第二种有些编译器不支持)
一般是这样声明柔性数组的。
struct S
{
char ch;
int arr[];//未定义大小,arr就是柔性数组
};
struct S1
{
char ch;
int arr[0];//另一种写法
};
使用了柔性数组的结构体其大小不会包含柔性数组的大小。如结构体S类型的大小还是1个字节。
声明之后我们该如何使其变大或是变小呢?这时候就可以用到我们的malloc函数来对他进行动态内存分配。结合之前介绍的特点,柔性数组应该这样使用。
#include<stdio.h>
#include<stdlib.h>
int main()
{
struct S
{
char ch;
int arr[];//未定义大小,arr就是柔性数组
};
struct S* s = (struct S*)malloc(sizeof(struct S) + 10 * sizeof(int));//给arr分配40个字节的空间
if (s == NULL)
return 1;
for (int i = 0; i < 10; i++)
{
s->arr[i] = i;
}
for (int i = 0; i < 10; i++)//打印
{
printf("%d ", s->arr[i]);
}
free(s);
s = NULL;
return 0;
}
当然如果变大以后不够用还可以继续变大(或者变太大了同样也可以变小)。
这时候会有些小伙伴说:如果我这样子写代码不是一样可以实现么?
#include<stdio.h>
#include<stdlib.h>
int main()
{
struct S
{
char ch;
int* arr;//定义一个指针来代替柔性数组
};
struct S* s = (struct S*)malloc(sizeof(struct S));
if (s == NULL)
return 1;
s->arr = (int*)malloc(10 * sizeof(int));//分配给arr指向的空间40个字节大小的空间
if (s->arr == NULL)
return 1;
for (int i = 0; i < 10; i++)
{
s->arr[i] = i;
}
for (int i = 0; i < 10; i++)//打印
{
printf("%d ", s->arr[i]);
}
free(s->arr);//要先释放arr不然找不到arr了
s->arr = NULL;
free(s);
s = NULL;
return 0;
}
这样写代码一样可以达到刚才的效果,但是为什么不推荐呢?有以下两个理由。
1,方便内存释放:
如果我们的代码是在一个给别人用的函数之中,你在里面做了二次内存分配,并把整个结构体返回给了用户。用户调用free可以释放结构体,但是用户并不知道这个结构体内的成员也需要free,所以你不能指望用户来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存一次性分配好 了,并返回给用户一个结构体指针,用户做一次free就可以把所有的内存也给释放掉。
2,有利于访问速度:
连续的内存有益于提高计算机的访问速度,也有益于其减少内存碎片。
柔性数组的知识就分享到这里,如果觉得博主讲的不错请给博主一个关注和收藏鼓励一下,那么我们下期再见,拜拜!