C++通过new/delete操作符进行动态内存管理
操作内置类型
void Test { int* ptr1 = new int; //动态申请一个int类型的空间 int* ptr2 = new int(10);//动态申请一个int类型的空间并初始化为10 int* ptr3 = new int[10];//动态申请10个int类型的空间 delete ptr1; delete ptr2; //释放单个空间 delete[] ptr3;//释放连续的空间 }操作自定义类型
申请自定义类型空间时,new会调用构造函数,delete会调用析构函数
new
调用operator new申请空间 在申请的空间执行构造函数delete
在申请的空间执行析构函数 调用operator delete释放空间new[n]
调用operator new[n]申请空间,实际调用operator new完成对n个对象空间的申请 在申请的空间执行n次构造函数delete[n]
在申请的空间执行n次析构函数 调用operator delete[n]释放空间,实际调用operator delete来释放空间相同
都是从堆上申请空间,并且需要手动释放
不同
malloc/free是函数,new/delete是操作符malloc/free只负责动态分配内存空间,new/delete除了动态分配内存空间还会调用构造函数完成对象的初始化和调用析构函数完成空间资源的清理malloc需手动计算大小且返回值为void*,使用时必须强转,new不需要计算大小,并且返回对应类型的指针malloc申请失败返回NULL,new申请失败会抛异常,所以malloc使用需判空,new使用需捕获异常new/delete比malloc/free效率低点,因为new/delete底层封装了malloc/free内存泄漏并不是指内存在物理上消失,而是指应用程序分配某段内存后,失去了对该段内存的控制,即动态开辟的内存空间未释放
后果
后果是慢性的,程序会越来越慢,内存越来越小,最终导致程序崩溃
分类
堆内存泄漏:程序执行中通过malloc/calloc/realloc/new等在堆中分配的一块内存,用完必须调用相应的free或delete释放内存,否则会导致堆内存泄漏系统内存泄漏:程序使用系统分配的资源,例如:套接字、文件描述符、管道等没有对应函数释放掉,会导致系统内存泄漏避免
事前预防:工程前期良好的设计规范,养成良好的编码对法,申请的内存匹配释放;采用RAII思想或指针指针来管理资源事后查错:使用内存泄漏工具检测