CD32.【C++ Dev】类和对象(22) 内存管理(下)
目录
1.定位new表达式
作用
格式
代码示例
分析
2.malloc/free和new/delete的区别
记忆方法
Myclass* ptr = (Myclass*)malloc(sizeof(Myclass)); + if (ptr == nullptr) {...}
free(ptr) + ptr = nullptr;
Myclass* ptr = new Myclass;
delete ptr
3.内存泄漏
内存泄漏分类
Windows下内存泄漏检测方案
内存泄漏测试工具
内存泄露检测工具比较
承接CD31.【C++ Dev】类和对象(21) 内存管理(中)文章
1.定位new表达式
作用
对已分配的空间显式调用构造函数
格式
//注:place_address必须是一个type*的指针,initializer-list是初始化列表
new (place_address) type//默认构造
//或者
new (place_address) type(initializer-list)
代码示例
#include <iostream>
using namespace std;
typedef int DataType;
class Myclass
{
public:Myclass(int):_val1(0xFF),_val2('2'),_val3(3.14){cout << "Myclass(int)" << endl;}~Myclass(){cout << "~Myclass" << endl;_val1 = 0;_val2 = '\0';_val3 = 0;}int _val1;char _val2;float _val3;
};int main()
{Myclass* ptr = (Myclass*)malloc(sizeof(Myclass));new(ptr)Myclass(0);ptr->~Myclass();ptr = nullptr;//手动为ptr置空return 0;
}
分析
ptr指向已经开辟好的空间(暂时不是一个对象),而new(ptr)Myclass(0);对ptr指向已有的空间显式调用构造函数Myclass(0),这里由于定义中Myclass(int)需要传参,这里随便传一个参数0
new(ptr)Myclass(0)执行后:
注:ptr是内置类型(任何类型的指针都是内置类型),不会自动调用析构函数
ptr->~Myclass()为手动调用析构函数:
ptr指向这个对象,则可以使用ptr调用这个对象的公共成员函数
ptr = nullptr手动为ptr置空:
定位new表达式在实际中一般是配合内存池使用,因为内存池分配出的内存没有初始化,所以如果是自定义类型的对象,需要使用new的定义表达式进行显示调构造函数进行初始化
2.malloc/free和new/delete的区别
相同点:
都是从堆上申请空间,并且需要用户手动释放
不同点:
1. malloc和free是函数new和delete是操作符
2. malloc申请的空间不会初始化,new可以初始化
3. malloc申请空间时,需要手动计算空间大小并传递.new只需在其后跟上空间的类型即可,如果是多个对象,[]中指定对象个数即可
4. malloc的返回值为void*,在使用时必须强转,new不需要,因为new后跟的是空间的类型
5. malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需要捕获异常
6. 申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理
记忆方法
从代码上记忆:
Myclass* ptr = (Myclass*)malloc(sizeof(Myclass));
if (ptr == nullptr)
{perror("malloc fail");return -1;
}
free(ptr);
ptr = nullptr;try
{Myclass* ptr = new Myclass;delete ptr;ptr = nullptr;
}
catch (const exception& e)
{cout << e.what() << endl;
}
Myclass* ptr = (Myclass*)malloc(sizeof(Myclass)); + if (ptr == nullptr) {...}
malloc是函数,( )中要放参数,大小为字节(第1点)
sizeof(Myclass): 手动计算空间大小并传递给malloc(第3点)
(Myclass*): malloc的返回值为void*,在使用时必须强转(第4点)
if (ptr == nullptr) {...}: malloc申请空间失败时,返回的是NULL,因此使用时必须判空(第5点)
malloc只会开辟空间,不会调用构造函数(第6点)
free(ptr) + ptr = nullptr;
free只会释放空间,不会调用析构函数,结束后需要手动置空(第6点)
Myclass* ptr = new Myclass;
new是操作符,不必像malloc函那样写括号(第1点)
new Myclass或new Myclass[?]:new只需在其后跟上空间的类型即可,如果是多个对象,[]中指定对象个数即可(第3点)
new等价为operato new和构造函数(先申请空间再构造): new可以初始化(第2点) ew在申请空间后会调用构造函数完成对象的初始化)(第6点)
try { } catch (...) { }: new不需要,但是new需要捕获异常(第5点)
delete ptr
delete在释放空间前会调用析构函数完成空间中资源的清理(第6点)
3.内存泄漏
之前在71.【C语言】动态内存管理(重点)(4)文章中提到过,补一些其他部分
内存泄漏分类
堆内存泄漏和系统资源泄漏
Windows下内存泄漏检测方案
https://thatonegamedev.com/cpp/memory-profiling-on-windows-for-c/
内存泄漏测试工具
来源:https://www.52pojie.cn/thread-997085-1-1.html
微软官方出品的Notmyfault软件,是Windows系统内核内存泄漏的工具
下载地址:https://pan.baidu.com/s/1R6qJfwOyJ2cjZozrw-Filg?pwd=9iak
提取码: 9iak
(可以指定内存泄漏的速度)
内存泄露检测工具比较
https://www.cnblogs.com/liangxiaofeng/p/4318499.html