柔性数组从C99开始支持使用
1.柔性数组的概念
概念:
结构体中,结构体最后一个元素允许是未知大小的数组,这就叫[柔性数组]的成员
struct S
{
int n;
char arr[]; //数组大小未知(柔性数组成员)
};
柔性数组的特点:
结构体中柔性数组成员前必须至少有一个其他成员
sizeof返回的这种结构大小不包括柔性数组的内存
struct S { int n; char arr[]; }; int main() { printf("%zu\n", sizeof(struct S);); //4 return 0; }
由图可知sizeof计算时不会包含柔性数组的大小
2.如何给柔性数组开辟空间呢?
如果结构体中有柔性数组,那么系统应该这么帮结构体开辟空间
怎样使用:
#include <stdio.h>
#include <stdlib.h>
typedef struct S
{
int n;
char arr[];
}S;
int main()
{
//sizeof(char)*10 根据需求改变,柔性数组就是可变数组
S* ptr = (S*)malloc(sizeof(S) + sizeof(char) * 10);
if (ptr == NULL)
{
perror("S::malloc");
return 1;
}
//ptr->n = 4;
int i = 0;
for (i = 0; i < 10; i++)
{
ptr->arr[i] = 'a';
}
for (i = 0; i < 10; i++)
{
printf("%c ", ptr->arr[i]);
}
// free(ptr);
// ptr = NULL;
//增容
S* pc = (S*)realloc(ptr, sizeof(S) + sizeof(char) * 20);
if(pc == NULL)
{
perror("S::realloc");
return 1;
}
else
{
ptr = pc;
}
free(ptr);
ptr = NULL;
return 0;
}
3.如果我们给柔性数组申请了动态内存会不会改变结构体大小?
不会!!!
#include <stdio.h>
#include <stdlib.h>
typedef struct S
{
int n;
char arr[];
}S;
int main()
{
//sizeof(char)*10 根据需求改变,柔性数组就是可变数组
S* ptr = (S*)malloc(sizeof(S) + sizeof(char) * 10);
if (ptr == NULL)
{
perror("S::malloc");
return 1;
}
printf("%zu", sizeof(S));
free(ptr);
ptr = NULL;
return 0;
}
运行结果:
形式如图所示:
可以看到申请了空间之后还是4字节
包含柔性数组的结构体用malloc()函数进行内存的动态分配,并且分配的内存大小应该大于结构体的大小,以适应柔性数组的预期大小
4.使用字符型指针代替柔性数组
typedef struct S
{
int n;
char* str;
}S;
int main()
{
printf("%zu", sizeof(S));
return 0;
}
运行结果:
进行代替
#include <stdio.h>
#include <stdlib.h>
typedef struct S
{
int n;
char* str;
}S;
int main()
{
S* ptr = (S*)malloc(sizeof(S));
if (ptr == NULL)
{
perror("malloc");
return 1;
}
ptr->n = 4;
ptr->str = (char*)malloc(sizeof(char) * 10);
if (ptr->str == NULL)
{
perror("ptr->str::malloc");
return 1;
}
int i = 0;
for (i = 0; i < 10; i++)
{
ptr->str[i] = 'a';
}
for (i = 0; i < 10; i++)
{
printf("%c ", ptr->str[i]);
}
//增容
char* pc =(char*)realloc(ptr->str, sizeof(char) * 20);
if(pc != NULL)
{
ptr->str = pc;
}
else
{
perror("pc::realloc");
return 1;
}
//释放顺序不要弄反,也可以先释放pc
//如果先释放ptr,ptr->str就没有了
free(ptr->str);
ptr->str = NULL;
free(ptr);
ptr = NULL;
return 0;
}
这个形式如图:
5.柔性数组的好处
虽然用char* str也可以实现,但是有弊端
使用柔性数组的好处:
->1.malloc 只需要使用一次
->2.free 只需要使用一次
->3.空间是连续的
与char* str相比
不容易出错
内存碎片少,空间利用率高
效率高(访问速度相对快)