在c语言我们知道了内存有代码段,数据段,堆区和栈区
代码段存放可执行的代码和只读常量
数据段存放全局变量和静态变量
堆进行动态内存分配,向上增长
栈存放非静态局部变量、函数参数和返回值,向下增长
而c语言动态内存管理有malloc、calloc和realloc,对他们的释放有free
到了c++之后,c语言动态内存的开辟和释放已经满足不了要求了,于是就有了new和delete
int* p1 = new int; //new 一个int int* p2 = new int[10]; //new 十个int int* p3 = new int(10); //new 一个为10的int
但是[]和()不能结合起来,new十个值为10的int是不行的
需要注意的是new出来的对象需要delete,new[]的需要delete[],如果不匹配可能会出问题
int* p1 = new int; int* p2 = new int[10]; delete p1; delete[] p2; //需要匹配
对于int这样的基本数据类型来说,new和malloc除了用法没什么区别,他们的区别在自定义类型上,对于自定义类型使用malloc只会开对应大小的空间,而new不仅会开空间,还会调用它的构造函数,所以与之对应的delete也会调用对应的析构函数并释放空间
再讲malloc和new在开辟空间失败上的不同,malloc失败后会返回一个空指针,所以我们在malloc后会assert(p)或是if(p==NULL),而new失败会抛出异常
对于它抛出的异常我们是可以捕获的
try
{
void* p = new char[1024 * 1024 * 1024];
}
catch (const exception& e)
{
cout << e.what() << endl;
}
可以看到它会返回bad allocation,意思就是所需的内存不足
当我们new一个自定义类型的时候,会先去调用operator new函数,operator new函数会使用malloc来申请空间,申请成功就返回,接着在申请的空间上调用构造函数,申请失败则抛出异常。那么delete则会先调用析构函数,然后调用operator delete释放空间
当然operator new也可以单独调用,但是我们这样开出来的空间怎么去初始化呢,我们又不能去调用它的构造函数,我们可以使用定位new表达式在已分配的内存上调用构造函数进行初始化
Date* p = (Date*)operator new(sizeof(Date)); new(p)Date(2022, 5, 29);



