【C语言】柔性的数组是什么?C/C++程序的内存开辟又是?
创始人
2024-05-12 13:05:11
0

本文主要讲解柔性数组的相关知识点,并穿插一下C/C++程序的内存开辟,涉及到动态内存管理函数,如有不了解的,请参考这一篇文章【C语言】小王带您轻松实现动态内存管理(简单易懂)_小王学代码的博客-CSDN博客

目录

前言

一、C/C++程序的内存开辟

1.1 初步分析内存

1.2 详细分析内存管理

二、柔性数组

2.1 柔性数组的特点

2.2 柔性数组的使用

2.3 柔性数组的优势

总结


前言

首先,我们知道在程序编译、运行的过程中,程序中的变量等会再内存中申请空间,这个时候呢,就需要我们来了解一下,C/C++程序的内存开辟是什么情况。

其次,我们都知道数组,知道数组是在编译的时候,就已经固定了内存空间,元素大小,那么什么又叫做柔性数组呢,是不是我们所想的那样,可以任意变化数组大小呢?

接下来,让小王带领大家一一探讨!!!


一、C/C++程序的内存开辟

我们一定想知道,到底C/C++程序在运行过程会将内存分为几部分,是如何划分的?

首先有一个简易图,让我们大致了解一下,变量放在哪,动态管理函数又放在哪?

内存空间可以初步分为:栈区、堆区、静态区

如图所示:

1.1 初步分析内存

栈区:主要是局部变量和函数形参在这个地方占用空间

堆区:动态内存管理函数malloc、free、calloc、realloc等等函数申请空间

静态区:存放全局变量、静态变量 

有关于堆区的这些函数可以去上一篇函数去看看,静态区也没什么好讲的,主要是全局变量和静态变量。

全局变量:在整个程序中所有函数之内都可以使用,可以更改内容,只在程序结束时退出

静态变量:由static修饰的变量,可以更改内容,在程序结束的时候才会失去对空间的使用权

栈区,由一个常见的小问题,返回栈区空间问题

如图所示:

1.2 详细分析内存管理

我们将内存更加细致的分为,内核空间、栈、内存映射段、堆、数据段、代码段

如图所示:

C/C++程序内存分配的几个区域:

1. 栈区(stack):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返回地址等。
2. 堆区(heap):一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。分配方式类似于链表。
3. 数据段(静态区)(static)存放全局变量、静态数据。程序结束后由系统释放。
4. 代码段:存放函数体(类成员函数和全局函数)的二进制代码

有了上图,我们就可以更加清晰的认知到,由static来静态修饰局部变量的意义了,相当于改变了生命周期。

实际上普通的局部变量是在栈区分配空间的,栈区的特点是在上面创建的变量出了作用域就销毁。
但是被static修饰的变量存放在数据段(静态区),数据段的特点是在上面创建的变量,直到程序结束才销毁
所以生命周期变长。

二、柔性数组

柔性数组,是C99标准中,结构中的最后一个元素允许是未知大小的数组,这就是柔性数组成员

例如:

typedef struct Node {int i;int arr[];//这就是柔性数组成员//或者是这样的情况:int arr[0]//int arr[0] 中的零并没有实际意义,并不是说明0个元素,这只是柔性数组的标识
};

2.1 柔性数组的特点

1.结构中的柔性数组成员前面必须至少一个其他成员。        
2.sizeof 返回的这种结构大小不包括柔性数组的内存。
3.包含柔性数组成员的结构用malloc ()函数进行内存的动态分配,并且分配的内存应该大于  结构的大小,以适应柔性数组的预期大小

图示解释:

2.2 柔性数组的使用

实际上柔性数组的使用和其他数组的使用是没有什么区别的,只是说,柔性数组是一种方式,可以在不知道需要多大的数组元素个数的时候,使用, 这样在后面可以根据自己所需,申请适当空间大小的数组来使用。所以是柔性的,普通数组是固定死的

代码演示:


typedef struct Node {int i;int arr[];//这就是柔性数组成员//或者是这样的情况:int arr[0]//int arr[0] 中的零并没有实际意义,并不是说明0个元素,这只是柔性数组的标识
}Node;
int main()
{int sz = sizeof(Node);printf("%d\n", sz);//4  只算除了柔性数组的其他成员的内容Node* p = (Node*)malloc(sizeof(Node)+10*sizeof(int));//创建 p结构体的空间,sizeof(Node)为int i 的空间 10*sizeof(int) 是留给柔性数组的空间for (int i = 0; i < 10; i++) {p->arr[i] = i + 1;}for (int i = 0; i < 10; i++) {printf("%d ", p->arr[i]);}free(p);return 0;
}

根据自己所需,我们设计了10个int类型元素的数组arr

2.3 柔性数组的优势

我们现在可能反应回来了,可能有人在问,这个柔性数组,我们也可以这样搞呀!

代码演示:


struct S {int n;int* arr;
};
int main()
{//先申请结构体的空间struct S* s = (struct S*)malloc(sizeof(struct S));//赋值s->n = 10;//再申请int*的空间s->arr = (int*)malloc(sizeof(int) * 10);//这样申请到了10个整型大小的空间for (int i = -0; i < 10; i++) {s->arr[i] = i + 1;}for (int i = 0; i < 10; i++) {printf("%d ", s->arr[i]);}free(s->arr);//先取消s.arr的空间并置为NULL,如果先s置为NULL,再滞空arr 的时候会警告s->arr = NULL;free(s);//要注意先后顺序,先内部的arr free滞空,再s free滞空s = NULL;return 0;//防止错误吧,逻辑问题
}

我们能看到,这样的代码也能实现柔性数组那样的功能啊,确实是可以实现的,但是我们来分析一下,使用柔性数组有什么优势呢?

第一:方便内存释放

如果我们的代码是在一个给别人用的函数中,你在里面做了二次内存分配,并把整个结构体返回给用户。用户调用free可以释放结构体,但是用户并不知道这个结构体内的成员也需要free,所以你不能指望用户来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存一次性分配好了,并返回给用户一个结构体指针,用户做一次free就可以把所有的内存也给释放掉。

第二:这样有益于访问速度

连续的内存有益于提高访问速度,也有益于减少内存碎片。(其实,我个人觉得也没多高了,反正你跑不了要用做偏移量的加法来寻址)

就是说使用柔性数组,只需要malloc一次、free一次、且空间是连续的

非柔性数组,需要malloc两次、free一次、且空间不是连续的


总结

这里我们就知道了,C/C++程序的内存分配是什么情况,简易的内存分配可以怎么描述?更加细致的分配,我也在本文中讲解了,最后是对于柔性数组的分析和使用,可能有些小伙伴觉得,哎,好像这个柔性数组没有什么太大的用处啊,我可以用别的方法实现呀(有讲),实际上这是C语言给我们提供的一种解决问题的思路或者是方式,不需要深究,我们知道,会用即可!!!

那么本文就到此结束了,下一篇文章,我们来讲述一下,文件操作是如何使用的,相关函数又是如何,可以对通讯录做升级处理啦!!!

相关内容

热门资讯

美国不提安卓系统华为,迈向自主... 华为与美国:一场关于技术、市场与政策的较量在当今这个数字化的世界里,智能手机已经成为我们生活中不可或...
安卓系统怎么打开ppt,选择文... 你有没有遇到过这种情况:手里拿着安卓手机,突然需要打开一个PPT文件,却怎么也找不到方法?别急,今天...
谷歌退回到安卓系统,探索创新未... 你知道吗?最近科技圈可是炸开了锅,谷歌竟然宣布要退回到安卓系统!这可不是一个简单的决定,背后肯定有着...
安卓系统待机耗电多少,深度解析... 你有没有发现,手机电量总是不经用?尤其是安卓系统,有时候明明没怎么用,电量就“嗖”的一下子就下去了。...
小米主题安卓原生系统,安卓原生... 亲爱的手机控们,你是否曾为手机界面单调乏味而烦恼?想要给手机换换“衣服”,让它焕然一新?那就得聊聊小...
voyov1安卓系统,探索创新... 你有没有发现,最近你的手机是不是变得越来越流畅了?没错,我要说的就是那个让手机焕发青春的Vivo V...
电脑刷安卓tv系统,轻松打造智... 你有没有想过,家里的安卓电视突然变得卡顿,反应迟钝,是不是时候给它来个“大保健”了?没错,今天就要来...
安卓系统即将要收费,未来手机应... 你知道吗?最近有个大消息在科技圈里炸开了锅,那就是安卓系统可能要开始收费了!这可不是开玩笑的,这可是...
雷凌车载安卓系统,智能出行新体... 你有没有发现,现在的汽车越来越智能了?这不,我最近就体验了一把雷凌车载安卓系统的魅力。它就像一个聪明...
怎样拍照好看安卓系统,轻松拍出... 拍照好看,安卓系统也能轻松搞定!在这个看脸的时代,拍照已经成为每个人生活中不可或缺的一部分。无论是记...
安卓车机系统音频,安卓车机系统... 你有没有发现,现在越来越多的汽车都开始搭载智能车机系统了?这不,咱们就来聊聊安卓车机系统在音频方面的...
老苹果手机安卓系统,兼容与创新... 你手里那台老苹果手机,是不是已经陪你走过了不少风风雨雨?现在,它竟然还能装上安卓系统?这可不是天方夜...
安卓系统7.dns,优化网络连... 你有没有发现,你的安卓手机最近是不是有点儿“慢吞吞”的?别急,别急,让我来给你揭秘这可能与你的安卓系...
安卓手机系统怎么加速,安卓手机... 你有没有发现,你的安卓手机最近变得有点“慢吞吞”的?别急,别急,今天就来给你支几招,让你的安卓手机瞬...
小米note安卓7系统,探索性... 你有没有发现,手机更新换代的速度简直就像坐上了火箭呢?这不,小米Note这款手机,自从升级到了安卓7...
安卓和鸿蒙系统游戏,两大系统游... 你有没有发现,最近手机游戏界可是热闹非凡呢!安卓和鸿蒙系统两大巨头在游戏领域展开了一场激烈的较量。今...
安卓手机没有系统更,揭秘潜在风... 你有没有发现,现在安卓手机的品牌和型号真是五花八门,让人挑花了眼。不过,你知道吗?尽管市面上安卓手机...
充值宝带安卓系统,安卓系统下的... 你有没有发现,最近手机上的一款充值宝APP,在安卓系统上可是火得一塌糊涂呢!这不,今天就来给你好好扒...
安卓系统8.0镜像下载,轻松打... 你有没有想过,想要给你的安卓手机升级到最新的系统,却不知道从哪里下载那个神秘的安卓系统8.0镜像呢?...
安卓系统修改大全,全方位修改大... 你有没有想过,你的安卓手机其实是个大宝藏,里面藏着无数可以让你手机焕然一新的秘密?没错,今天就要来个...