内存四区(栈区stack,堆区heap,全局区、代码区code)



1、划分内存四区的意义

C语言程序中,根据是 局部变量,全局变量,常量 还是通过 malloc 等类似的函数分配内存空间,把他们放到对应的 内存区中。这样就赋予了这些变量或常量不同的生命周期,不同的释放方式。

根据我们程序的需要,我们在编码过程中,声明不同的变量类型,使他们有不同的声明长度,不同的释放方式,给我们更大的灵活编程。

2、内存四区分类

序号区域描述
1栈区(stack)保存函数现场(形参、返回地址、相关运行状态)、函数内局部变量
栈顶高地址低地址的方向生长

由程序管理,发生出栈时释放
2堆区(heap)malloc/freenew/delete
低地址高地址的方向生长

由程序员 手动释放
3数据区(1)全局区/静态区:初始化的全局变量/静态变量在一块区域,未初始化的全局变量/静态变量在相邻的另一块区域
(2)常量区:存放常量,一般是字符串常量

由OS管理,程序结束时 才释放
4代码区(code)各个函数体的二进制代码

由OS管理,程序结束时 才释放

3、内存堆栈图

在这里插入图片描述

4、栈和堆的比较


4.1 申请方式

:由系统自动分配。
:需要程序员自己申请,并指明大小。在C中用 malloc 函数,在C++中用 new 运算符。

4.2 存储内容、数据

:在函数调用时,第一个 进栈 的是主函数中的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数。

  1. 在大多数的C编译器中,参数是 由 右往左 入栈 的,然后是函数中的局部变量
    (注意:静态变量是 不入栈的)
  2. 当本次函数调用结束后,局部变量出栈,然后是参数,最后 栈顶指针 指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。

:一般是在 的头部用一个字节,存放 的大小。
中的具体内容由程序员安排。

4.3 申请后系统的响应

:只要 的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示 溢出。

:操作系统有一个记录空闲内存地址的 链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的 堆节点,然后将该节点从 空闲节点链表 中删除,并将该节点的空间分配给程序。
对于大多数系统,会在这块 内存空间 中的 首地址 处记录本次分配的大小。这样,代码中的 delete 语句才能正确地释放本内存空间。
另外,由于找到的 堆节点 的大小不一定正好等于申请的大小,系统会自动地将多余的那部分重新放入 空闲链表 中。

4.4 申请大小的限制

是向 低地址 扩展的 数据结构,是一块连续的内存的区域。
栈顶 的地址和 的最大容量是系统预先规定好的,在Windows下, 的大小是2MB(也有的说是1MB,总之是一个编译时就确定的常数)。
如果申请的空间超过 的剩余空间,将提示overflow。因此,能从 获得的空间较小。

是向 高地址 扩展的 数据结构,是不连续的内存区域。
这是由于系统是用链表存储空闲内存地址的,自然是不连续的。而 链表 的遍历方向是由 低地址高地址
的大小,受限于计算机系统中,有效的虚拟内存
由此可见, 获得的空间比较灵活,也比较大。

4.5 申请效率

:由 系统自动分配,速度较快。但程序员无法控制。

:是由new分配的内存,一般速度比较慢。
而且容易产生内存碎片,不过用起来最方便。


4.6 存取效率

的数据存取 比 的快。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值