C语言中,对柔性数组的理解

在漫长的代码之路的开端,我先学习了C语言,之后我打算再学习C++。
在学习过程中对学习中遇到的问题,我一般会分享出我自己的理解和观点,当然,随时欢迎指正。
在C99之前是没有柔性数组的概念的。
要了解什么是柔性数组、柔性数组的存在有什么好处。先看一下柔性数组的特点吧:
1:结构中的柔性数组成员前面必须至少-个其他成员。
2:sizeof返回的这种结构大小不包括柔性数组的内存。
3:包含柔性数组成员的结构用malloc()函数进行内存的动态分配,并且分配的内存应该大于结构的大小, 以适应柔性数组的预期大小。
总体上来看柔性数组也可以理解为:
结构体最后一个元素是未知大小的数组,而且数组的大小是可调整的结构体里面的成员,当然,编译器还需要支持C99,不过现在大部分编译器都支持的吧~~
那么刚开始提出的柔性数组的存在有什么好处呢?
用两个代码例子来作为分析:
我将把我的理解大部分写在代码的注释上
代码1:

  typedef struct ad
{
	int i;
	int a[0]; //柔性数组成员。最后一个成员,可以是未知大小的。int a[];和int a[0];这两种写法意义相同,只不过在不同编译器可能不同
}type_a;
int main()
{
	//type_a a;
	//printf("%d\n", a);   //输出为4,不包含柔性数组的大小,这里验证了柔性数组特点的第2条
	//如何使用? 
	type_a *ps = (type_a*)malloc(sizeof(type_a) + 5 * sizeof(int));// 5 * sizeof(int)相当于给后面的柔性数组开辟的大小20个字节,连带着柔性数组前的int类型大小也一起进行了空间的开辟。需要注意的是:ps指向的还是i变量的初始地址
	ps->i = 100;
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		ps->a[i] = i; //
		printf("%d ", ps->a[i]);
	}
	type_a *ps1 = realloc(ps, 44); // 假设在开辟空间需要再次调整加5个int类型字节的时候,要理解这句代码是整体结构体的大小字节 ,其中还有i的4个字节,不要搞错了
	if (ps1 == NULL) ps = ps1;   //判断开辟成功与否
	for (i = 5; i < 10; i++)
	{
		ps->a[i] = i;
		printf("%d ", ps->a[i]);   //验证打印
	}
	free(ps);       //回收开辟空间
	ps = NULL;      //特别注意的一点,回收释放后ps虽然空间地址被回收,但未清零,需要再次赋值为空指针
	return 0;
}

代码1基于动态内存开辟的过程对柔性数组的使用进行了操作。
再次强调,大部分理解我都在代码中有注释。
代码1无非就是想随时调整柔性数组的大小来存放数据。那么其实不用柔性数组也可以办得到。怎么做呢?
代码2:

 typedef struct ad
{
	int i;
	int *arr;  
}type_a;
int main()
{
	type_a *ps = (type_a*)malloc(sizeof(type_a));//开辟的空间是结构体的总和,ps指向的结构体的空间
	ps->arr = malloc(5 * sizeof(int));   //这里只开辟了arr的大小空间
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		ps->arr[i] = i;
		printf("%d ", ps->arr[i]);
	}
	//调整大小
	type_a *ps1 = realloc(ps->arr, 10 * sizeof(int));  //只在arr后面追加了5个int类型大小的空间
	if (ps1 == NULL) ps = ps1;
	for (i = 5; i < 10; i++)
	{
		ps->arr[i] = i;
		printf("%d ", ps->arr[i]);
	}
	free(ps->arr);
	ps->arr = NULL;
	free(ps);  //这里需要多次释放,因为上面两次开辟的空间不同
	ps = NULL;
	return 0;
}

看到这里,你会发现代码2多次使用了malloc函数,malloc用的越多,内存碎片就越多。而且需要多次释放。
相对比较之下:
那柔性数组的好处是什么呢?
1:方便内存释放
2:有利于访问速度

局部性原理中:指CPU访问存储器时,无论是存取指令还是存取数据,所访问的存储单元都趋于聚集在一个较小的连续区域中。
对于访问速度方面,听了鹏哥的讲解,加上我的理解是:
因为每一次开辟的时候,都不一定是开辟连续的空间。内存空间是连续的情况下有利于CPU访问,因为寄存器的速度>cache高速缓存>内存>硬盘
众所周知,CPU的访问速度是非常快的,而内存的读写速度比较慢,那怎么办呢?一般把内存的数据放到高速缓存里面,高速缓存里面的数据放到寄存器里面
CPU每次处理数据的时候先向寄存器读取,读取的时候,数据如果连续,附近的数据就有时间从内存到高速缓存,再从高速缓存到寄存器。CPU再次读取的时候直接从寄存器读取
如果数据存放不连续的话,数据有可能就没时间到寄存器,那就降低了CPU访问数据的速度。
那么,柔性数组为甚没火起来呢?哈哈哈~
有兴趣的自行了解了~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值