内存申请的方式
- malloc:只负责申请空间,申请到的空间是一个随机值。
- realloc:申请空间或调整原有空间。释放是只需要释放返回的空间。
- calloc:申请并初始化空间(全部初始化为0)。
- new
内置类型
//申请空间
int* p = new int;
//申请并初始化空间,申请了1个字节,内容为10
int* p1 = new int(10);
//申请一个连续的空间,10表示元素个数,申请了40个字节,内容为随机值
int* p3 = new int[10];
- delete
内置类型
//释放空间
delete p;
//释放连续空间,[]中不用写数字
delete[] p3;
delete p4;
注意:申请和释放都要保持一致,前三种用free释放,new用delete来释放,还要注意是否为连续内存。
自定义类型
对于自定义类型,new会先自己申请空间再调用构造函数进行初始化。
对于自定义类型delete会先调用析构函数进行资源清理再自己进行对象的空间清理。
//申请连续的空间必须有默认构造函数存在
//申请空间+调用10次构造函数
A* arr = new A[10];
//调用带参构造函数
A* p = new A(1, 2);
//调用10次析构 + 对象清理
delete[] arr;
malloc/free和new/delete的异同:
同:都是在堆上申请内存空间,并且需要手动释放
异:1、malloc/free是函数,new/delete是操作符
2、malloc只是申请内存,而new既申请内存又调用构造函数初始化内存
3、malloc在申请内存时需要手动计算大小并传递,new只需要在后面跟上空间类型即可
4、malloc的返回值是void*,使用时需要强转类型,new只需要在后面跟上空间类型即可
5、若是申请失败,malloc会返回空指针,因此使用时必须判空,而new需要捕获异常
6、delete在释放空间之前会调用析构函数进行资源清理
内存泄漏
内存泄漏是什么?
是指因为疏忽或错误造成程序未能释放已经不使用的内存。在物理上不是说内存消失了,实质是应用程序分配某段内存之后,因为错误失去了对该段内存的控制,因而造成了内存浪费。
危害:导致响应越来越慢导致卡死
一般有堆内存泄漏和系统内存泄漏
堆内存:指的是程序执行中依据须要分配通过malloc / calloc / realloc / new等从堆中分配的一块内存,用完后必须通过调用相应的 free或者delete 删掉。假设程序的设计错误导致这部分内存没有被释放,那么以后这部分空间将无法再被使用,就会产生Heap Leak(堆泄露)。
系统内存:指程序使用系统分配的资源,比方套接字、文件描述符、管道等没有使用对应的函数释放掉,导致系统资源的浪费,严重可导致系统效能减少,系统执行不稳定。
怎样避免内存泄漏呢?
最重要的就是从源头上扼制内存泄漏出现的可能性:要有良好的代码规范,申请内存就要记着释放。
但有时会在还没有执行到释放语句时程序出错,导致内存泄漏,这时可以使用智能指针