柔性数组的简单介绍和使用


前言

也许你从未听说过柔性数组这个概念,但它确实存在。C99中,结构体中的最后一个成员允许是未知大小的数组,这就叫柔性数组成员


1.柔性数组是什么?

结构体中的最后一个成员允许是未知大小的数组,这就叫柔性数组成员

struct S
{
	int n;
	int arr[];//未知大小的柔性数组成员,数组的大小是可以调整的
};
int main()
{
	struct S s;
	printf("%d\n",sizeof(s));//计算次结构体大小输出 4 并没有计算arr数组的大小
	return 0;
}

我们创建的柔性数组一般用法:

struct S
{
	int n;
	int arr[];
};
int main()
{
	//创建一个结构体指针ps,给它动态分配4+20个字节的内存
	struct S* ps = (struct S*)malloc(sizeof(struct S) + 5*sizeof(int));
	return 0;
	//可以使用arr这个柔性数组
	free(ps);
	ps = NULL;
	return 0;
}

2.柔性数组有哪些好处呢?

我们先看如下两个代码

  • 代码1 使用柔性数组实现功能
struct S
{
	int n;
	int arr[];
};
int main()
{
	//创建一个结构体指针ps,给它动态分配4+20个字节的内存
	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;//给数组arr赋值 0 1 2 3 4
	}
	free(ps);
	ps = NULL;
	return 0;
  • 代码2 使用常用的嵌套指针的方式实现功能
struct S
{
	int n;
	int* arr;
};
int main()
{
	struct S* ps = (struct S*)malloc(sizeof(struct S));
	ps->arr = malloc(5*sizeof(int));
	int i = 0
	for (i=0;i<5;i++)
	{
		ps->arr[i] = i;//给数组arr赋值 0 1 2 3 4
	}
	//释放两个开辟的内存
	free(ps->arr);
	ps->arr = NULL;
	free(ps);
	ps = NULL;
	return 0;

代码1 和 代码2 都可以实现arr数组大小的灵活调整。但是代码1有两个好处:

  1. 方便内存的释放
    如果我们的代码是在一个给别人用的函数中,你在里面做了二次内存分配,并把整个结构体返回给用户,用户调用free可以释放结构体但是用户并不知道这个结构体内的成员也需要free,所以你不能指望用户来发现这个事。所以我们把结构体的内存以及成员要的内存一次性分配好了,并返回给用户一个结构体指针,用户做一次free就可以把所有内存给释放调。
  2. 提高访问速度
    连续的内存有利于提高访问速度,也有利于减少内存碎片

3.柔性数组特点

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

例如:

struct S
{
	int n;//柔性数组成员前面必须存在的成员
	int arr[];
};
int main()
{
	//此结构体内存的大小为 4
	struct S s;
	printf("%d\n",sizeof(s));//计算次结构体大小输出 4 并没有计算arr数组的大小
	//给它动态分配4+20个字节的内存  24>4
	struct S* ps = (struct S*)malloc(sizeof(struct S) + 5*sizeof(int));
	return 0;
}

总结

  以上就是今天要讲的内容,本文仅仅简单介绍了柔性数组这块,就是自己平时上课时的笔记和一些心得。

  希望对看到的大家有所帮助!!!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值