C/C++中的内存管理

1.C/C++内存分区模型

C++程序在执行时,会将程序大方向分为四个区域:代码区,全局区,堆区,栈区。

在这里插入图片描述

2.程序运行前

在程序编译后,生成了exe可执行文件,未执行该程序前分为两个区域。

2.1代码区(代码段)

存放常量和程序代码(二进制代码)的区域。
1.代码区是共享的,共享的目的是对于频繁被执行的程序,只需要在内存中有一份代码即可。
2.代码区是只读的,原因是防止程序意外修改了他的指令。

2.2数据段(静态区/全局区)

存放全局变量和静态数据,程序结束时由系统释放。(用static修饰的变量(栈区)会存入静态区, 改变其生命周期, 程序结束时由系统释放)

3.程序运行后

3.1栈区

由编译器自动分配释放,存放函数的参数值,局部变量等。
不要返回局部变量的地址,栈区开辟的数据由编译器自动释放

#include<iostream>
using namespace std;
int* func()
{
	int a = 10;//局部变量 存放在栈区 函数执行完后自动释放
	return &a;//返回局部变量的地址
}
int main()
{
	int* p = func();
	cout <<"*p=" <<*p << endl;
	cout << "*p=" << *p << endl;
	system("pause");
	return 0;
}

栈上的局部变量被释放,第二次打印出来的结果为随机值。
在这里插入图片描述

1.栈区处于相对较高的地址, 栈地址是向下(向低地址)增长的, 是一块连续的内存的区域。
2.在执行函数时, 函数中的局部变量(不包括局部静态变量)在栈中存放。
3.函数执行完毕这些局部变量都会被释放, 栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 栈区主要存放运行函数时分配的局部变量、函数参数、返回数据、返回地址。

3.2堆区

动态分配的内存在堆区。由程序员分配和释放,若程序员不释放(不及时释放会造成内存泄漏), 则程序运行结束时会由操作系统收回。

1.首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的动态开辟内存的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的 C中free()函数(C++中delete语句)才能正确的释放申请的内存空间。此外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。
2.C中由动态开辟内存的函数( malloc(), calloc(), realloc() )分配(C++中由new分配), 速度较慢, 易产生内存碎片, 但使用比较方便
3.堆是由低地址向高地址扩展的,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。堆获得的空间比较灵活,也比较大。

3.3堆与栈的区别

①申请和回收
栈:系统自动完成
堆:程序员完成(如果不及时手动回收会造成内存泄漏,所以一般要由程序员完成)
②申请效率
栈:较快(栈内存分配运算内置于处理器的指令集中,效率高)
堆:较慢(C中由动态开辟内存的函数 malloc(), calloc(), realloc() 分配(C++中由new分配, 较慢)
③申请大小的限制
栈:较小 (在Windows下,栈的大小是2M,也有的说是1M,总之是一个编译时就确定的常数)
堆:大 (堆的大小受限于计算机系统中有效的虚拟内存)
④堆和栈的中的存储内容
栈:在函数调用时,第一个进栈的是主函数中函数调用后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后函数中的局部变量依次入栈。函数调用结束时, 先入栈的后出栈, 后入栈的先出栈。
堆:堆中的具体内容由程序员决定。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值