上一篇 sizeof和strlen区别 内存泄漏 malloc原理
new/delete操作符进行动态管理
malloc
new/delete操作内置类型
源码查看
malloc,free和new delete区别
对象在栈上,编译器负责开启/释放空间,在堆上new/delete开启/释放空间
new的实现原理
成功后返回调用构造函数
delete实现原理
- 调用析构函数—将对象中的资源清理干净
- 调用operator delete(void* pt)
new[]实现原理
delete[]实现原理
new操作符,操作符new,placement-new
new操作符
- new操作符---->用来申请空间的new关键字T*pt = new T;
操作符new
- 操作符new----->是一个函数,比如: void* operator new(size_t size);注意:该函数是可以重现实现的,一般情况下不需要重载—直接库提供的就可以,除非有特殊的需求----比如:申请空间时顺便打印日志信息–帮助定位内存泄漏
#include <iostream>
#include <windows.h>
using namespace std;
void* operator new(size_t size)
{
cout << "operator new(size_T)" << endl;
return malloc(size);
}
int main()
{
int* pt1 = new int;
delete(pt1);
return 0;
}
源码
placement-new定位new
定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象 源码 调用定位new相当于调用下面的函数
总结区别malloc new free delete
malloc/free和new/delete的共同点是:都是从堆上申请空间,并且需要用户手动释放。不同的地方是:
- malloc和free是函数,new和delete是操作符
- malloc申请的空间不会初始化,new可以初始化
- malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可
- malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型
- malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需要捕获异常
- 申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理
内存泄漏
- 堆内存泄漏(Heap leak)
堆内存指的是程序执行中依据须要分配通过malloc / calloc /realloc / new等从堆中分配的一块内存,用完后必须通过调用相应的 free或者delete 删掉。假设程序的设计错误导致这部分内存没有被释放,那么以后这部分空间将无法再被使用,就会产生Heap Leak。 - 系统资源泄漏
指程序使用系统分配的资源,比方套接字、文件描述符、管道等没有使用对应的函数释放掉,导致系统资源的浪费,严重可导致系统效能减少,系统执行不稳定。
如何检测
避免
- 工程前期良好的设计规范,养成良好的编码规范,申请的内存空间记着匹配的去释放。ps:这个理想状态。但是如果碰上异常时,就算注意释放了,还是可能会出问题。需要下一条智能指针来管理才有保证。
- 采用RAII思想或者智能指针来管理资源。
- 有些公司内部规范使用内部实现的私有内存管理库。这套库自带内存泄漏检测的功能选项。
- 出问题了使用内存泄漏工具检测。ps:不过很多工具都不够靠谱,或者收费昂贵。
总结一下: 内存泄漏非常常见,解决方案分为两种:1、事前预防型。如智能指针等。2、事后查错型。如泄漏检测工具。
|