c语言 关于柔性数组在内存中的优势(C99,VS2019)

首先我们知道,在c/c++中内存区域的划分

(画的真丑)

 一般定义的变量在栈中,动态内存分配(malloc,calloc,realloc)在堆中,static修饰的变量存放在静态库中。

接下来先简单看一下柔性数组

1.结构中的柔性数组成员前面必须至少一个其他成员

2.sizeof返回的这种结构大小不包括柔性数组内存

3.包含柔性数组成员的结构用malloc()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小

三句话看起来有点长但其实举个例子很好理解,话不多说,先定义:

#include<stdio.h>
#include<stdlib.h>

struct stu {
	int n;     //结构中的柔性数组成员前面必须至少一个其他成员
	int a[];   //柔性数组a[]
};

int main()
{
	printf("%d\n", sizeof(struct stu));//输出结果为:4  sizeof返回的这种结构大小不包括柔性数组内存 

	struct stu* p = (struct stu*)malloc(sizeof(struct stu) + sizeof(int) * 10);//假设我们希望a[]可以存储十个整形数据 
	//包含柔性数组成员的结构用malloc()函数进行内存的动态分配,
	//并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小

	if (p == NULL)
	{
		return 1;
	}
	free(p);
	p = NULL;
	return 0;
}

简单画个图,应该是这样子的:

 既然空间都是malloc出来的,那就可以调整了,这就体现柔性的特点

于是:

 别急别急,我们先看看内存中的效果

    p->n = 10;
	int i = 0;
	for (i = 0; i < 10; i++) 
	{
		p->a[i] = i;
	}

 要是内存不够,我们只需要:

struct stu* ps=(struct stu*)realloc((struct stu*)sizeof(struct stu)+sizeof(int)*20)
//增加20个int
if(ps!=NULL)
{
    P=PS;
}

是不是跟用指针一样?简单一看确实一样。

别急,我们先说说realloc

我们知道realloc申请内存是这样子的:

1.当后面内存足够大时,直接申请到。

2.当后面内存不够时,另找一段区域,将原本的内存区拷贝过去,再加上新申请的内存,并且释放原来的内存。

3.实在没内存给你用了,返回空指针。 

 

 

 我们再看看用指针的效果

#include<stdio.h>
#include<stdlib.h>

struct stu {
	int n;    
	int *a;  
};

int main()
{
	struct stu *p=(struct stu*)malloc(sizeof(struct stu));
	if (p == NULL)
	{
		return 1;
	}
	return 0;

 简单画个图,应该是这样子的:

 a指针要指向一个空间,我们又要开辟一个:

    p->a =(int *)malloc(sizeof(int));
    if(p->a==NULL)
    {
        return 1;
    }

我们看看内存中的效果

(为了区别上一张,n没有赋值。)

看上去一摸一样,但是当我们要增加内存时:

int *ps= (int*)realloc(p->a,sizeof(int)*10);
	if (ps != NULL)
	{
		p->a = ps;
	}

又多出一个指针,有点晕了,这还没完,当我们使用完,释放内存时,还需要先把新增内存段释放,再释放原本的内存段,要是先回收了原本的空间,那么新增的空间指针都找不到了,当场就是内存泄漏,所以我们不得不:

	free(p->a);
	p->a = NULL;
	free(p);
	p = NULL;

麻烦是麻烦点,可毕竟也达到柔性数组的效果了,那大佬们就喜欢指针咋办。

其实虽然达到了效果,但回想一下,我们用指针两次开辟空间,再想想上面所说的realloc开辟空间的方法,是不是想到了什么。没错,要是全部都是原本的空间后面有足够的内存给你开辟还好说,可是哪能这么好,毕竟在操作系统眼里你就是个要饭的,就怕哪次后面没有足够的内存,随便在堆区找一块连续的满足要求的开辟,在内存空间中造成大量内存碎片,这些内存碎片不大不小的,再次被利用的可能性比较低,使内存使用效率变低,更增大开辟失败几率(可能有这么多内存,但都是碎片化不连续的,用不了嘛),而柔性数组就解决了这个问题,所以说柔性数组的使用还是有必要的。

本人浅显的一些理解,有不到位或者错误的地方欢迎大家指出。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值