柔性数组

柔性数组 

c语言并没有柔性数组这个概念,但他又是实际存在的,结构体中最后一个成员是数组,且未规定内存大小,即可理解为柔性数组

柔性数组的特点
1.结构体中柔性数组的成员前面至少有一个其他成员
2.sizeof计算结构体大小是不包含柔性数组的内存
3.包含柔性数组成员的结构应用malloc进行开辟内存空间,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小

1. 

struct S
{
	int a;
	int arr[];//大小未知,有的写成int arr[0]也是可以的
};

此时arr就是一个柔性数组

2.

struct S
{
	int a;
	int arr[];
};
int main()
{
	printf("%d", sizeof(s));//计算柔性数组的大小,是不包含柔性数组的,只计算它前面的变量
	return 0;
}

运行的结果是

4

也就是不包括柔性数组的大小,只有他前面成员的大小 

2.柔性数组应该用malloc进行开辟空间,而不是直接对其进行赋值

struct S
{
	int a;
	int arr[];
};
int main()
{
	struct S s={0};//用malloc函数进行分配,正常不会这样使用
	
	printf("%d", sizeof(s));//计算柔性数组的大小,是不包含柔性数组的,只计算它前面的变量
	return 0;
}

 正确的使用应该是这样的

struct S
{
	int a;
	int arr[];//大小未知,有的写成int arr[0]也是可以的
};

int main()
{
	struct S* ptr = (struct S*)malloc(sizeof(struct S) + 10*sizeof(int));//10*sizeof(int)给数组的,后面的大小可以通过realloc进行改变
	ptr->a = 10;
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		ptr->arr[i] = i;
	}
	struct S* ps = (struct S*)realloc(ptr, sizeof(struct S) + 20 * sizeof(int));
	if (ps != NULL)
	{
		ptr = ps;
	}
	printf("%d", ptr->arr);
	free(ptr);
	ptr = NULL;
	return 0;
}

可能会有人认为将结构体中的数组改为指针也可以

struct s
{
	int a;
	int *arr;//在栈上开辟
};
int main()
{
	struct s* ps = (struct s*)malloc(sizeof(struct s));
	if (ps == NULL)//先对ps这个指针判断空指针
	{
		return 1;
	}
	ps->a = 10;
	ps->arr = (struct s*)malloc(sizeof(10 * sizeof(int)));
	if (ps->arr == NULL)//arr也是一个指针,所以也要判断是否是空针
	{
		return 1;
	}
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		ps->arr[i] = i;//达到和之前一样的效果
	}
	//增加
	int*ptr = (int*)realloc(ps->arr, 20 * sizeof(int));
	if (ptr != NULL)
	{
		ps->arr = ptr;
	}
	//使用

	//释放,ps,和arr都是被malloc开辟出来,要先free指针空间,再free,ps的空间
	free(ps->arr);
	ps->arr = NULL;
	free(ps);
		ps = NULL;//但是这是有不足的地方,这不是柔性数组,进行了两次malloc同时就会对应两次free,malloc开辟次数越多,内存碎片也越多,内存利用率也就降低了,内存局部性原理,每次使用都是在他周边范围使用

	return 0;
}

但实际上他malloc开辟了两次空间,留了过多的内存碎片,使得内存的利用率降低,

优势.方便开辟。方便释放 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zevin~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值