目录
知识回顾:
⭐有关柔性数组开辟动态内存管理的博文
C语言之动态内存管理篇(malloc和free、realloc、calloc)——优快云博客
⭐有关柔性数组中自定义类型的博文
一、什么是柔性数组
柔性数组即数组大小待定的数组,在 C 语言中可以在结构体的最后一个元素使用长度为 0 的数组来实现。
在 C 语言中,柔性数组是一种特殊的数组定义方式。它通常作为结构体的最后一个成员出现,其形式为一个未指定长度的数组类型。
也许你从来没有听说过柔性数组这个概念,但是它确实是存在的。C99中,结构中的最后一个元素允许是未知大小的数组,这就叫做【柔性数组】成员。
其代码如下所示:
写法①:
typedef Struct st_type
{
int i;
int a[0];//柔性数组成员
}type_a;
注:有的编译器下写法①会报错
写法②:
Struct S
{
int n;
int arr[];//大小是未知的
};
二、柔性数组的特点
- 结构中的柔性数组成员前面必须至少一个其他成员变量。
- sizeof 返回的这种结构大小不包括柔性数组的内存。
- 包括柔性数组成员的结构用 malloc() 函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。
例如:
typedef Struct st_type
{
int i;
int a[0];//柔性数组成员
}type_a;
printf("%d\n",sizeof(type_a));//输出结果是4
三、柔性数组的使用
在使用柔性数组时,需要我们手动开辟内存空间,并且对内存进行调整,我们用mallohenc进行内存的开辟,使用realloc对内存进行调整扩充。
struct S
{
int n;
int arr[0];//未知大小的数组 - 柔性数组成员
};
int main()
{
struct S* ps = (struct S*)malloc(sizeof(struct S) + 10*sizeof(int));
if (ps == NULL)
{
perror("malloc");
return 1;
}
int i = 0;
ps->n = 10;
for (i = 0; i < 10; i++)
{
ps->arr[i] = i;
}
for (i = 0; i < 10; i++)
{
printf("%d ", ps->arr[i]);
}
free(ps);
ps = NULL;
return 0;
}
运行结果如下:
四、柔性数组与其他的比较
以下两段代码所要展现的效果是一样的,不过他们有不同的思路,下面来看柔性数组的应用代码:
Struct S
{
int n;//所占大小为4个字节
int arr[0];//大小未知
};
int main()
{
//期望arr的大小是10个整形
Struct S*ps=(Struct S*) malloc(sizeof(struct S)+10*sizeof(int));
ps->n=10;
int i=0;
for(i=0;i<10;i++)
{
ps->arr[i]=i;
}
//增加、扩充
Struct S*ptr=(struct S*)realloc(ps,sizeof(struct S)+20*sizeof(int);
if(ptr!=NULL)
{
ps=ptr;
}
//使用
//释放
free(ps);
ps=NULL;
return 0;
}
下面是用其他代码来编写的,其想要达成的效果一样:
Struct S
{
int n;
int arr[];
};
int main()
{
Struct S*ps=(Struct S*)malloc(sizeof(struct S));
if(ps==NULL)
return 1;
ps->n=10;
ps->arr=(int*)malloc(10*sizeof(int));
if(ps->arr==NULL)
return 1;
int i=0;
for(i=0;i<10;i++)
{
ps->arr[i]=i;
}
//扩容
int * ptr=(int*)realloc(ps->arr,20*sizeof(int));
if(ptr!=NULL)
{
ps->arr=ptr;
}
return 0;
}
注: 这种方法虽然也达到了实现了相应的功能,但是和第一种相比还是有很多不足,这里我们不是用柔性数组开辟的空间,而是用指针的方式申请的空间内存,这里我们用到了两次malloc,两次malloc对应两次free,这样的场景下容易出错。而上面包含柔性数组的方式malloc的次数更少一些,更不容易出错,相对来说更好。
五、内存碎片
内存碎片是指在计算机内存分配过程中产生的不连续的、无法被有效利用的内存空间。 当我们在申请堆空间的时候,空间与空间之间的间隔,也就是内存碎片。
六、柔性数组的好处
第一:方便内存释放
使用柔性数组可以在一次内存分配中同时为结构体和柔性数组分配空间。这样可以简化内存管理,减少分配和释放内存的次数,提高程序的效率。由于柔性数组的长度可以在运行时根据实际需求进行调整,所以可以很方便地适应不同大小的数据。
第二:有利于提高访问速度
连续的内存有利于提高访问速度,也有益于减少内存碎片(个人感觉也没多高,反正跑不了要用做偏移量的方法来寻址)