柔性数组 - 在结构体中定义数组时,并不指定数组的大小,后面用malloc函数为数组开辟空间。
使用案例如下:
struct S
{
int n;
int arr[];//未知大小,或arr[0]
//柔性数组成员 - 数组的大小是可调整的
};
int main()
{
struct S s;
printf("%dn", sizeof(s));//4 并不包含柔性数组的大小
struct S* ps = (struct S*)malloc(sizeof(struct S)+5*sizeof(int));
//可以动态开辟数组的空间
ps->n = 100;
int i = 0;
for (i = 0; i < 5; i++)
{
ps->arr[i] = i;//0 1 2 3 4
}
struct S* ptr=realloc(ps, 44);//调整开辟的空间大小
if (ptr != NULL)
{
ps = ptr;
}
for (i = 5; i < 10; i++)
{
ps->arr[i] = i;
}
for (i = 0; i < 10; i++)
{
printf("%d ", ps->arr[i]);
}
//释放
free(ps);
ps = NULL;
return 0;
}
首先是定义结构体 ,在定义结构体时,数组arr[ ]中,[ ]内为空或者0,不给定数组的大小,即为定义了柔性数组。这时如果用sizeof求数组的大小,则求的是除了柔性数组之外的数组大小。
然后定义一个结构体指针ps指向malloc开辟的内存空间地址,用开辟的此内存空间的大小来定义柔性数组的大小,例如:
struct S* ps = (struct S*)malloc(sizeof(struct S)+5*sizeof(int));
上面这行代码开辟的内存空间大小为除柔性数组之外的大小,加要定义的柔性数组的大小。
可以通过结构体指针对该结构体的内容进行修改:
ps->n = 100;
int i = 0;
for (i = 0; i < 5; i++)
{
ps->arr[i] = i;//0 1 2 3 4
}
使用realloc函数调整ps(柔性数组)的大小:
struct S* ptr=realloc(ps, 44);
记得在使用完开辟的内存空间后,使用free函数和赋值空指针的代码进行内存释放:
free(ps); ps = NULL;
柔性数组也可以是指针数组:
struct S
{
int n;
int* arr;
};
int main()
{
struct S* ps =(struct S*) malloc(sizeof(struct S));
ps->arr = (int*)malloc(5 * sizeof(int));
int i = 0;
for (i = 0; i < 5; i++)
{
ps->arr[i] = i;
}
for (i = 0; i < 5; i++)
{
printf("%d ",ps->arr[i]);
}
//调整大小
int *ptr=realloc(ps->arr, 10 * sizeof(int));
if (ptr != NULL)
{
ps->arr = ptr;
}
for (i = 5; i < 10; i++)
{
ps->arr[i] = i;
}
for (i = 0; i < 10; i++)
{
printf("%d ", ps->arr[i]);
}
//释放内存
free(ps->arr);
ps->arr = NULL;
free(ps);
ps = NULL;
return 0;
}
注意:两次 malloc 函数用来开辟 int 和 int* 的空间,所以在代码最后要 free 两次。
柔性数组的特点:
最基本地,柔性数组一定是在结构体中体现出来;
另外:
1.结构中的柔性数组成员前面必须有至少一个其他成员(非柔性数组),就像第一段代码里的int n
2. sizeof 返回的这种结构大小不包括柔性数组的内存
3.包含柔性数组成员的结构用 malloc()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小
柔性数组的优点:
1.方便内存释放
2.连续的内存有利于提高访问速度,减少内存碎片
下面的代码段在开辟内存空间时需要使用2次malloc函数,会产生较多的内存碎片,内存浪费的多,并且内存不连续
局部性原理:局部性原理是指CPU访问存储器时,无论是存取指令还是存取数据,所访问的存储单元都趋于聚集在一个较小的连续区域中。
struct S
{
int n;
char c;
int arr[0];//柔性数组成员
int arr[];//柔性数组成员
};
int main()
{
struct S s;
return 0;
}



