栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

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

(画的真丑)

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

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

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

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

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

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

#include
#include

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

int main()
{
	printf("%dn", 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
#include

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

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/443802.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号