前言
这章主要讲内存分布、C++内存开辟和释放的新玩法、new和delete的实现原理
最后讲一些面试题,在面试时内存这一块问的也比较多,所以可以多看看书
推荐《深入理解计算机系统》
一、内存分布
注意:
- 栈是向下增长 、空间比较小、存放临时的数据
- 堆,空间比较大,可以向上增长
二、动态内存
1.malloc、calloc、realloc区别
- malloc是在堆上直接申请空间
- calloc在申请完空间后,将空间初始化为0
- realloc是扩容,分为原地扩和重新开辟
当后面空间足够时,直接扩增需要的空间,后面空间不够时,会在别的地方重新开辟一块空间,然后将原来的值拷贝过去,释放旧空间,返回新空间地址。
2.new和delete
- new的用法 new +类型 +[]个数 ,返回类型是指针
- new申请一个空间 后面不用 [ ]
- 在操作内置类型new和malloc效果完全一致,在操作自定义类型时,new会调用构造函数,malloc不会调用
- 方括号、圆括号不能同时出现
3.delete和free
注意:
- delete删除空间
- 如果要删除的空间只有一个,就不能加 [ ]
- 在操作内置类型free和delete效果完全一致,在操作自定义类型时,free会调用析构函数,delete不会调用
4.operator new &&operator delete(重点)
- operator new
与malloc一样用法完全一致
差别在于operator new在开辟空间失败时,会抛bad_alloc类型异常
而malloc失败则返回0
在底层上,operator是通过malloc实现
- operator free
效果、操作与free完全一致,在内存释放失败都会终止程序
而operator的出现则是为了配对operator new
- operator new的类专属重载(了解)
平时我们用的new是在堆上开空间,坏处就是访问速度慢,所以可以自己重载一个operaotor new
和operator delete 使数据在内存池申请和释放,提高效率,了解即可
三、new和delete实现原理
- 动态内存开辟和释放,一共学了三种malloc、operator new 、new || free、operator delete 、delete
- 对于申请内置类型 malloc和 operator new 基本一致,差别在operator new失败会抛异常,malloc则会返回NULL. 自定义类型free、delete和operator delete 完全一致,失败都是终止程序
- 对于自定义类型,malloc、operator new 都不会调用构造函数,new会调用构造. delete 会调用析构函数
- new T[N]表示开辟N个类型为T的空间,则调用N次构造函数
定位new(了解)
对于已经分配内存的原始空间,调用构造函数
格式:new (place_address) type
四、malloc、free与new、delete的区别(常见面试题)
- 效果:new会调用构造函数,失败抛异常,malloc失败返回NULL
- 概念:malloc是函数,new是操作符
- 用法:malloc参数传字节,返回值是void* ,new后跟类型,返回是类型的指针
五、内存泄漏(重点)
-
概念
:因为错误或者疏忽,造成程序没有释放已经不再使用的内存。失去了对某段内存的控制
-
危害
:长期运行的程序出现内存泄漏,会导致响应越来越慢,最终卡死
-
分类
: 1.堆泄漏。malloc、realloc、calloc、new开辟的内存没有释放,导致内存失去利用机会
2.系统资源泄漏:系统分配的资源没有使用对应的函数释放掉,导致系统不稳定。
-
避免
:事先检查(智能指针)
事后检查
总结
- 内存管理涉及程序的方方面面
- 知道代码在内存上位置
- 熟悉new和free操作与malloc的区别
- 防止内存泄漏,要养成良好的代码习惯,用完就销毁
————编程没有捷径