new和delete的运算符重载视角
new和malloc对比:
- malloc按字节开辟内存,返回void*,需要强制类型转换;new开辟内存需要指定类型
- new在malloc的基础上,还会进行数据的初始化
- malloc开辟内存失败返回nullptr,new抛出bad_alloc类型的异常
delete和free对比:
- delete是在free的基础上进行了析构
运算符重载视角
- 事实上,new是operator new的重载,delete也是operator delete的重载。全局空间下可以重载new和delete。
- 如何发现程序中的内存泄露?
- 编写全局作用域的new和delete的运算符重载方法,并自定义一个内存申请与释放的记录表,监视new和delete的记录。
- new和delete能混用吗?C++为什么可以区分单个元素和数组的内存分配和释放?blog参考
- 在new对象是,如果对象是单个元素,则直接开辟内存并初始化;如果对象是类对象(且显式定义了析构函数)的数组,则其malloc的空间为4字节+对象数组所需的空间,其中开头4字节用于保存数组长度,不过返回的是数组空间首地址。delete时,delete数组还需free开头四字节的部分。
- 如果new和delete仅针对简单编译器内置类型做内存开辟和释放,不涉及类对象构造析构,则不会报错
- 如果new和delete涉及类对象构造析构,且没有配对使用。
- 将单个对象delete[]:则代码执行会向前探索4字节以获取数组长度,报错。
- 将数组对delete,则释放第一个元素,不会报错,但存在内存泄漏。
using namespace std;
//先调用operator进行内存开辟,然后自动调用对象的构造函数
void* operator new(size_t size)
{
void* p = malloc(size);
if (p == nullptr)
throw bad_alloc();
cout << "operator new addr: " << p << endl;
return p;
}
void* operator new[](size_t size)
{
void* p = malloc(size);
if (p == nullptr)
throw bad_alloc();
cout << "operator new[] addr: " << p << endl;
return p;
}
void operator delete(void* ptr)
{
cout << "operator delete addr: " << ptr << endl;
free(ptr);
}
void operator delete[](void* ptr)
{
cout << "operator delete[] addr: " << ptr << endl;
free(ptr);
}
class Test
{
public:
Test(int data = 10) { cout << "Test()" << endl; }
~Test() { cout << "~Test()" << endl; }
private:
int* ptr;
};
int main()
{
try
{
Test* p1 = new Test[6];
//delete p1;//混用出现问题
delete []p1;
int* p = new int[3];
delete p; //内存泄露,不报错
int* q = new int(2);
delete[]q;
}
catch (const bad_alloc& err)
{
cerr << err.what() << endl;
}
}
标签:malloc,24new,运算符,内存,数组,重载,new,delete
From: https://www.cnblogs.com/sio2zyh/p/17977657