C语言柔性数组
C99中,结构(结构体)中的最后一个元素允许是未知大小的数组,这就叫做柔性数组成员
struct S
{
int i;
int arr[];//柔性数组成员--未知数组大小--数组的大小是可以调整的
};
有些编译器会报错无法编译可以改成:
struct S
{
int i;
int arr[0];//柔性数组成员
};
在有些编译器上,两种写法皆可
柔性数组的特点:
1.结构中的柔性数组成员前面必须至少有一个其他成员
2.用sizeof()计算结构大小不包括柔性数组的内存
3.包含柔性数组成员的结构用malloc()函数进行内存的动态分配,分配的内存应大于结构的大小,以适应柔性数组的预期大小
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
struct S
{
int i;
int arr[];//柔性数组成员
};
int main()
{
//struct S s1={0};
//printf("%d\n",sizeof(s1));
printf("%d\n", sizeof(struct S));//输出的是4
return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
struct S
{
int n;
int arr[];//柔性数组成员
};
int main()
{
struct S* ps = (struct S*)malloc(sizeof(struct S) + 5 * sizeof(int));
/*malloc()为n动态开辟sizeof(struct S)字节的内存空间,
为arr动态开辟5*sizeof(int)字节的内存空间,这块空间是连续的*/
ps->n = 26;
int i = 0;
for (i = 0; i < 5; i++)
{
ps->arr[i] = i + 1;
}
struct S* ptr = (struct S*)realloc(ps, 44);
//又为arr动态开辟20字节的内存空间
if (ptr != NULL)
{
ps = ptr;//realloc动态开辟内存成功
}
else
{
return 0;//动态开辟内存失败
}
for (i = 5; i < 10; i++)
{
ps->arr[i] = i + 1;
}
for (i = 0; i < 10; i++)
{
printf("%d ", ps->arr[i]);
}
free(ps);//释放ps所指向的那块动态开辟的空间(用完就释放,防止内存泄露)
ps=NULL;
return 0;
}
输出:
1 2 3 4 5 6 7 8 9 10
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
struct S
{
int n;
int* arr;
};
int main()
{
struct S* ps = (struct S*)malloc(sizeof(struct S));//8
//malloc动态开辟8字节的内存空间来存放n和arr(注意:arr是一个地址)
ps->arr =(int*) malloc(5 * sizeof(int));
//malloc动态开辟20字节的内存空间,将这块空间的地址返回给arr,通过arr可以找到这块空间
int i = 0;
for (i = 0; i < 5; i++)
{
ps->arr[i] = i;//可以联想一个整形数组,数组名就是数组首元素的地址
}
for (i = 0; i < 5; i++)
{
printf("%d ", ps->arr[i]);
}
//调整arr所指向的那块空间的大小
int* pa = (int*)realloc(ps->arr, 10 * sizeof(int));
if (pa != NULL)
{
ps->arr = pa;
}
else
{
return 0;
}
for (i = 5; i < 10; i++)
{
ps->arr[i] = i;
}
printf("\n");
for (i = 5; i < 10; i++)
{
printf("%d ", ps->arr[i]);
}
free(ps->arr);//先释放ps->arr指向的空间,再释放ps指向的那块空间,注意顺序
free(ps); //如果先释放ps所指向的那块空间,那么arr就被销毁了,曾经arr指向的那块空间就释放不了
ps->arr = NULL;
ps = NULL;
return 0;
}
输出:
0 1 2 3 4
5 6 7 8 9
这代码也可以实现柔性数组的功能,但是使用柔性数组有两个好处:一是方便内存释放,不需要像上面的那样也要释放结构体成员所指向的那块空间(释放两次),只需要我们做一次free就可以把所有动态开辟的内存释放掉;二是可以提高访问速度,连续的内存有利于提高访问速度,减少内存碎片.