个人主页:@Weraphael
✍作者简介:目前是C语言学习者
✈️专栏:C语言航路
希望大家多多支持,咱一起进步!
如果文章对你有帮助的话
欢迎 评论 点赞 收藏 加关注
说起数组,一维数组、二维数组、字符数组、整型数组和浮点型数组,我相信大家并不陌生吧,今天我们一起看看柔性数组!
在C99中,结构中的最后一个元素允许是未知大小的数组,我们把这样的数组称为柔性数组成员。
【定义】
struct S
{
int i;
int a[]; //柔性数组
};
若有些编译器无法编译,可以改成以下这种:
struct S
{
int i;
int a[0];//柔性数组成员
};
动态内存开辟函数讲解:传送门
#include
#include
struct S
{
int i;
char a[];
};
int main()
{
//包含柔性数组成员的结构用`malloc`函数进行动态内存分配
//并且分配的内存应该大于结构体大小
struct S* sp = (struct S*)malloc(sizeof(struct S) + 10 * sizeof(char));
//若sp为空指针,说明开辟动态内存失败
if (sp == NULL)
{
return 1;
}
//否则开辟成功
//使用
sp->i = 100;
for (int i = 0; i < 10; i++)
{
sp->a[i] = 'x';
}
//打印
for (int i = 0; i < 10; i++)
{
printf("%c ", sp->a[i]);
}
//释放
free(sp);
sp = NULL;
return 0;
}
甚至还能扩容
realloc
#include
#include
struct S
{
int i;
char a[];
};
int main()
{
//包含柔性数组成员的结构用`malloc`函数进行动态内存分配
//并且分配的内存应该大于结构体大小
struct S* sp = (struct S*)malloc(sizeof(struct S) + 10 * sizeof(char));
//若sp为空指针,说明开辟动态内存失败
if (sp == NULL)
{
return 1;
}
//否则开辟成功
//使用
sp->i = 100;
for (int i = 0; i < 10; i++)
{
sp->a[i] = 'x';
}
//扩容(多加10字节的空间)
struct S* p = (struct S *)realloc(sp, sizeof(struct S) + sizeof(char) * 20);
//如果p为空指针说明扩容失败
if (p == NULL)
{
return 1;
}
else
{
sp = p;
p = NULL;
}
for (int i = 10; i < 20; i++)
{
sp->a[i] = 'w';
}
//打印
printf("%d\n", sp->i);
for (int i = 0; i < 20; i++)
{
printf("%c ", sp->a[i]);
}
return 0;
}
除【柔性数组的使用】样例以外,也可以设计成下面这样:
#include
#include
struct S
{
int i;
char* a;
};
int main()
{
//为结构体开辟空间
struct S* sp = (struct S*)malloc(sizeof(struct S));
//若sp = NULL,说明开辟失败
if (sp == NULL)
{
return 1;
}
//否则开辟成功
//使用内存空间
sp->i = 100;
//为char* a开辟10个字节空间
sp->a = (char*)malloc(sizeof(char) * 10);
//使用
for (int i = 0; i < 10; i++)
{
sp->a[i] = 'w';
}
//或者还能为char* a扩容
char* p = (char*)realloc(sp->a, 20 * sizeof(char));
if (p == NULL)
{
return 1;
}
else
{
sp->a = p;
p = NULL;
}
//使用扩容的空间
for (int i = 10; i < 20; i++)
{
sp->a[i] = 'J';
}
//打印
printf("int i = %d\n", sp->i);
for (int i = 0; i < 20; i++)
{
printf("%c ", sp->a[i]);
}
//释放空间
free(sp->a);
sp->a = NULL;
free(sp);
sp = NULL;
return 0;
}
一个常见的问题:为什么要先释放
sp->a
的内存空间
柔性数组好处的总结:
- 对于柔性数组来说,开辟空间(malloc)只需要一个,释放空间(free)也只需要一次,且内存空间是连续的,而对于上面的代码来说,开辟空间需要二次,释放空间也同样需要二次,且内存空间是不连续的。所以它第一个好处是方便内存释放
- 连续的内存有益于提高访问速度