内存分配的方式
在C++中,内存被分为了五个区域,分别是,栈、堆、数据段、代码段、内存映射区。
- 栈:函数执行时,内部创建的局部变量的存储单元都存储在栈上。在程序执行结束时,系统会自动释放栈中的资源。栈内存分配的效率也是比较快的。栈是向下增长的。
- 堆:用于程序运行时动态内存分配,堆是向上增长的。
- 数据段:存储全局变量和静态变量的地方。
- 代码段:可执行代码/只读常量。
- 内存映射区:是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存,做进程间通信。
动态内存管理的方式
- new/delete
- malloc/free
以上俩种都是动态管理内存的方法。
俩者的区别:
- new 可以进行初始化而 malloc不可以
- malloc 返回的是void *指针,所以需要进行强制类型转化
- new/delete为运算符,malloc/free为函数
- new/delete失败会抛出异常或者调用失败处理函数,malloc/free 失败会返回NULL
- new初始化的时候会调用构造函数,而malloc只是开辟空间,不调用构造函数。
malloc/calloc/realloc 的区别
malloc :向内存申请一块连续可用的空间,并返回指向这块空间的指针。
void* malloc(size_t size);
如果开辟成功则返回一个指向开辟好空间的指针。
如果开辟失败,则返回一个nullptr指针,因此malloc指针一定要做检测
如果size为0,malloc的行为是未定义的,取决于编译器
calloc:向内存空间申请num个大小为size的空间,并初始化为0。
void* calloc(size_t num,size_t size);
与函数malloc的区别就是可以将申请的空间每个字节初始化为0
realloc:对动态开辟的内存大小进行调整
void* realloc(void* ptr,size_t size);
ptr是要调整的内存地址
size是调整后的大小
内存泄漏
内存泄漏是指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不是指内存在物理上消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。
内存泄漏的危害
长期运行的程序出现内存泄漏,会导致响应越来越慢,最终卡死。
内存泄漏的分类
- 堆内存泄漏:指程序通过malloc/calloc/realloc/new等从堆中分配的一块内存,用完后必须通过调用相应的free或者delete删掉。如果没有删掉,则会导致以后这部分空间无法使用。
- 系统资源泄漏:指程序使用系统分配的资源,例如套接字、文件描述符、管道等没有使用对应的函数释放掉,导致系统资源的浪费,严重可导致系统效能减少,系统执行不稳定。
如何避免内存泄漏
- 使用智能指针来管理资源
- 使用new、malloc等分配空间的情况时注意手动释放资源。
- 使用内存泄漏检测工具检测