【C语言】一篇带你了解 柔性数组的意义与如何使用

柔性数组是C99标准中的一种特性,允许结构体的最后一个元素为未知大小的数组。它在内存管理上提供了便利,如只需一次malloc和free即可管理结构体及其附加数组。与使用指针的方式相比,柔性数组减少了内存碎片,简化了内存管理,并降低了出错的可能性。然而,使用时需要注意正确分配和释放内存。
摘要由CSDN通过智能技术生成

柔性数组

  • 也许你从来没有听说过柔性数组(flexible array)这个概念,但是它确实是存在的。
  • C99 中,结构中的最后一个元素允许是未知大小的数组,这就叫做『柔性数组』成员。

例如:

typedef struct S
{
	int i;
	int a[0];//柔性数组成员
}S;

有些编译器会报错无法编译可以改成:

typedef struct S
{
	int i;
	int a[];//柔性数组成员
}S;

柔性数组的特点:

  • 结构中的柔性数组成员前面必须至少一个其他成员。
  • sizeof 返回的这种结构大小不包括柔性数组的内存。
  • 包含柔性数组成员的结构用malloc ,calloc等函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。

柔性数组的使用

代码1

#include<stdio.h>
#include<stdlib.h>
typedef struct S
{
	int i;
	int a[];//柔性数组成员
}S;

int main()
{
	//分配的内存应该大于结构的大小,以适应柔性数组的预期大小。
	S* s = (S*)malloc(sizeof(S) * sizeof(int) * 10);
    //判断s是否开辟成功
	if (s == NULL)
		perror("malloc:");

	//使用
	s->i = 100;
	int i = 0;

	//柔性数组使用
	for (i = 0; i < 10; i++)
	{
		s->a[i] = i;
	}
    //打印
	for (i = 0; i < 10; i++)
	{
		printf("%d ", s->a[i]);
	}
    //释放空间
    free(s);
	system("pause");
	return 0;
}

最终输出结果
0 1 2 3 4 5 6 7 8 9


柔性数组的优势

代码2

上述的 struct S结构也可以设计为结构中指针方案

#include<stdio.h>
#include<stdlib.h>
//代码2
typedef struct S
{
	int i;
	int* pa;//柔性数组成员
}S;

int main()
{
	S* s = (S*)malloc(sizeof(S));
	//判断s是否开辟成功
	if (s == NULL)
		perror("malloc:");

	int* ptr = (int*)malloc(sizeof(int) * 10);
	//判断是否开辟成功
	if (s->pa == NULL)
		perror("malloc:");
	else
		//开辟成功就还给s->pa使用
		s->pa = ptr;

	//使用
	s->i = 10;
	int i = 0;

	for (i = 0; i < 10; i++)
	{
		s->pa[i] = i;
	}

	for (i = 0; i < 10; i++)
	{
		printf("%d ", s->pa[i]);
	}

	//释放空间
	//先释放s->pa,如果先释放s就找不到s->pa了
	free(s->pa);
	s->pa = NULL;
	free(s);
	s = NULL;
	system("pause");
	return 0;
}

上述 代码1 和 代码2 可以完成同样的功能,但是 方法1 的实现有两个好处:

  • 代码1:
    malloc 1次 free 1次, 容易维护空间,不易出错malloc次数少,内存碎片就会较少,内存的使用率就较高一些

如果我们的代码是在一个给别人用的函数中,你在里面做了二次内存分配,并把整个结构体返回给用户。用户调用free可以释放结构体,但是用户并不知道这个结构体内的成员也需要free,所以你不能指望用户来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存一次性分配好了,并返回给用户一个结构体指针,用户做一次free就可以把所有的内存也给释放掉。

  • 代码2
    malloc 2次,free 2次,维护难度加大,容易出错内存碎片就会增多,内存的使用率就下降了

在这里插入图片描述


C语言中,动态数组柔性数组(flexible arrays)是两种处理数组大小的不同方法。 动态数组(也称为动态内存分配)通常是在程序运行时根据需要动态地分配和释放内存空间的数组。程序员需要使用`malloc()`或`calloc()`等函数来分配内存,并使用`free()`来释放内存。动态数组的大小在编译时并不固定,可以根据需要改变。由于数组大小的灵活性,它们更适用于需要频繁调整大小的情况,但对内存管理的要求较高。 柔性数组(在C99标准后引入)是数组的一种特殊形式,它允许数组名后面跟一个可选的省略的整数,这个整数表示数组的有效元素数量,但不是数组的实际大小。例如,`int arr[10]; int arr[];`中,`arr[]`就是一种柔性数组,编译器会自动为它预留一定数量的内存,直到遇到第一个非数组元素。柔性数组的最大好处是代码简洁,不需要显式指定大小,但它们的大小仍然受限于栈的大小,不能像动态数组那样任意增长,且不能跨多个函数调用。 相同点: - 都允许数组的大小在一定程度上具有灵活性。 - 可以在声明时不明确指定数组的大小。 不同点: - 动态数组:内存分配在运行时完成,可以在程序执行过程中创建和销毁。大小可动态调整,需要手动管理内存。 - 柔性数组数组大小在编译时确定,但可以通过数组名称后的省略整数部分灵活指定有效元素的数量,不能动态扩展,且受限于栈空间。 - 内存管理:动态数组需要程序员手动分配和释放内存,柔性数组由编译器自动管理,无需显式释放。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值