new和delete基本介绍
-
malloc
和free
是C函数 -
new
和delete
是C++的运算符 -
malloc
失败是通过返回值和nullptr
作比较;而new
开辟内存失败,是通过抛出bad_alloc
类型的异常来判断的 -
new
不仅可以做内存开辟,还可以做内存初始化操作 -
malloc
和new
的区别malloc
按字节开辟内存,new
开辟内存时需要指定类型malloc
只负责开辟空间,new
不仅仅有malloc功能,还可以进行数据初始化- malloc开辟内存失败返回nullptr, new则是抛出bad_alloc类型异常
-
free 和delete区别:
delete (int *)p;
调用析构函数,再调用free(p)
释放空间
new的几种使用方式
int main()
{
int *p1 = new int(20);
int *p2 = new (nothrow) int; // 不抛出异常
const int *p3 = new const int(40);
// 定位new
int data = 0;
// 在&data位置分配内存并初始化
int *p4 = new (&data) int(50);
cout << "data:" << data << endl; // 50
return 0;
}
重载new和delete运算符
#include <iostream>
using namespace std;
// 先调用operator new开辟内存空间,然后调用对象构造函数
void* operator new(size_t size)
{
void* p = malloc(size);
if (p == nullptr)
throw bad_alloc();
cout << "operator new addr:" << p << endl;
return p;
}
// delete p 先调用p指向的对象的析构然后调用operator delete释放内存
void operator delete(void* ptr)
{
cout << "operator delete addr:" << ptr << endl;
free(ptr);
}
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);
}
int main()
{
try
{
int* p = new int;
delete p;
int* q = new int[10];
delete[] q;
}
catch (const bad_alloc& err)
{
cerr << err.what() << endl;
}
return 0;
}
new[] 和delete 或者说new和delete[]能混用吗?C++如何区分单个元素和数组内存分配和释放
不能混用,数组new[]
时,编译器会在开头多分配4B空间记录new对象的数量
class Test
{
public:
Test(int data = 10) { cout << "Test()" << endl; }
~Test() { cout << "~Test()" << endl; }
private:
int ma;
};
int main()
{
Test* p1 = new Test[5];
delete[] p1; // 从operator delete(p1-4),即从最顶上存储对象的数量的内存起始地址开始释放
}
注意返回的地址不是最顶上的地址!!
若混用new[]和delete:
Test* p1 = new Test[5]; // 输出operator new[] addr:0157F6C0
cout << "p1:" << p1 << endl; // p1:0157F6C4
delete p1;
可以看出返回的是p1[0]
对象的地址,调用delete p1
也只是析构p1[0]
对象,不合法,抛出异常
若混用new
和delete[]
更好理解,delete[]
会传入【new返回的地址-4】来调用析构,这块空间根本就没分配,必然就出错
可以通过重载new和delete来解决内存泄漏