文章目录
注:转载请标明原文出处链接: https://lvxiaowen.blog.csdn.net/article/details/107009692
1 什么是内存管理?
2 内存分配方式
2.1 从静态存储区域分配
内存在程序编译的时候就已经分配好了,这块内存在程序的整个运行期间都存在。
例如全局变量,static静态成员变量
2.2 在栈(stack)上创建
执行函数时,函数内部变量的存储单元可以在栈上创建,函数执行结束时这些存储单元自动释放。栈内存分配运算置于处理器的指令集中,效率很高,但是分配的内存容量有限。
2.3 在堆(heap)上分配
也称为动态内存分配。程序在运行的时候用malloc或new申请任意多少内存,程序员自己负责在何时用free或delete来释放这块内存。动态内存的生命周期由程序员决定,使用非常灵活,但如果在堆上分配了空间,就有责任回收它,否则运行的程序会出现泄漏,频繁地分配和释放不同大小的堆空间将会产生堆内碎块。也就是我们常说的内存碎片。
3 堆和栈的区别
(1) 管理方式: 栈由编译器自动管理,无需手工控制;堆释放工作由程序员控制,容易产生memory leak。
(2) 空间大小: 一般来讲在32位系统下,堆内存可以达到4G的空间。但栈一般都是有一定的空间大小的。
(3) 碎片问题: 对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。栈则不会存在这个问题。
(4) 生长方向: 堆的生长方向是向上的,也就是向着内存地址增加的方向;栈的生长方向是向下的,是向着内存地址减小的方向增长。
(5) 分配方式: 堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由alloca函数进行分配,但是栈的动态分配和堆是不同的,它的动态分配是由编译器进行释放,无需手工实现。
(6) 分配效率: 栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。
4 内存的申请和释放
申请内存:int *p = new int;
释放内存:delete p;
申请块内存:int *arr=new int[10];
释放块内存:delete []arr;
内存申请是否一定成功?释放内存需要注意什么?
5 malloc/free与new/delete
(1) malloc/free是C程序中的库函数,需要头文件支持;new/delete是C++中的操作符,可以被重载。删除数组delete []p,指针释放后,要将指针置空。
(2) malloc和new都是在堆上分配内存。
(3) malloc分配内存失败时返回NULL;new内存分配失败时,会抛出bac_alloc异常。
(4) malloc/free是面向内存的,不可以调用构造函数和析构函数;new/delete是面向对象的,可以调用构造函数和析构函数,new可认为是malloc+构造函数。
(5) malloc不能初始化对象;new可以,如int *p = new int(2)。
(6) malloc返回的指针是void 类型,需要通过强制类型转换将void指针转换成我们需要的类型;而new返回的指针是它分配空间的类型。
参考资料
[1] https://www.imooc.com/learn/381
[2] C++内存管理
[3] 经典面试题之new和malloc的区别