当前位置: 代码迷 >> 综合 >> c语言 关于柔性数组在内存中的优势(C99,VS2019)
  详细解决方案

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

热度:32   发布时间:2023-12-06 06:32:52.0

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

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

  相关解决方案