C++提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。
1、new/delete操作内置类型
int main()
{
//C
int* p1 = (int*)malloc(sizeof(int));
free(p1);
//CPP
int* p2 = new int;
delete p2;
//C
int* p3 = (int*)malloc(sizeof(int) * 10);
free(p3);
//CPP 申请10个int的数组
int* p4 = new int[10];
delete[] p4;
//CPP 申请一个数组,并且初始化为10
int* p5 = new int(10);
delete p5;
int* p6 = new int[10] {1, 2, 3};
delete[] p6;
return 0;
}
在动态申请内置类型的数据上,new/malloc除了用法上面,其他方面没什么区别。
2、new和delete操作自定义类型
struct ListNode
{
int _val;
struct ListNode* _next;
ListNode(int x)
:_val(x)
, _next(NULL)
{}
};
int main()
{
//开空间+调用构造函数
ListNode* n1 = new ListNode(1);
ListNode* n2 = new ListNode(2);
return 0;
}
在自定义类型数据上面:
new/malloc除了用法上面的不同,还有一个重大区别,new和delete会调用构造函数初始化,析构函数清理。
3、operator new与operator delete函数
new在底层调用operator new全局函数来申请空间,delete在底层通过 operator delete全局函数来释放空间。
4、定位new
定位new表达式在实际中一般是配合内存池使用。因为内存池分配出的内存没有初始化,所以如果是自定义类型的对象,需要使用new的定义表达式进行显示调构造函数进行初始化。
class A
{
public:
A(int a = 0)
: _a(a)
{
cout << "A():" << this << endl;
}
~A()
{
cout << "~A():" << this << endl;
}
private:
int _a;
};
int main()
{
// p1现在指向的只不过是与A对象相同大小的一段空间,还不能算是一个对象,因为构造函数没有执行
A* p1 = (A*)malloc(sizeof(A));
// 显示调用构造函数
new(p1)A(1); // 注意:如果A类的构造函数有参数时,此处需要传参
p1->~A();
free(p1);
return 0;
}