众所周知,C可以说是C++的一个子集吧!C中也包含动态内存管理,C中动态内存管理,离不开malloc和free函数,而C++动态内存管理,即继承了C的动态内存管理,又有自己的创新。而这创新便是new和delete操作符的出现。
既然有创新,那必然意味着有所不同。其所不同主要有三点:其一不同便是:new,delete是操作符,而malloc和free是函数。其二便是malloc/free只是动态分配内存空间/释放空间。而new/delete除了分配空间/释放空间还会调用构造函数/析构函数进行初始化/清理。其三不同是malloc需要手动计算类型大小且返回值是void* ,new可以自动计算类型的大小,返回对应类型的指针。
在C++中存在着类似malloc和free的函数如下:
其实operator new/operator delete只负责分配空间和释放空间,并不会调用对象的构造函数和析构函数来初始化/处理对象。
new->调用operator new开辟空间->使用构造函数初始化->
delete->使用析构函数处理对象->调用operator delete释放空间->
注:当new所针对的对象为内置类型时,则不会调用构造函数和析够函数
如下图所示,便是new,delete对于不同对象所对应的不同的处理。
将new和delete应用于自定义类型且创建的为非数组变量。
在使用new的时候会将创建的变量的大小以参数的形式传递给operator new函数,而operator new函数又调用maolloc函数来开辟空间,operator new的返回值保存到寄存器中,并且调用构造函数来初始化该返回值所对应的那块空间。完成之后,将寄存器中的内容复制给pa。...在对象空间被销毁之前,调用析构函数处理问题,而所谓的问题便有可能是处理该类中成员变量采用new申请的空间。
随后便是调用operator delete函数去释放A类对象所在的空间!
下图是使用new[]和delete[]创建自定义类型的数组
关于C++动态内存的最后一点便是定位New的使用。
定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象。
如下,是使用定位New和构造函数及析构函数来模拟new和delete操作符。
class A { private: int _a; int* _ptr; public: A(int a=1) :_a(a) , _ptr(NULL) { cout << "A()" << endl; _ptr = new int(3); } ~A() { cout << "~A()" << endl; delete _ptr; } }; void test() { A* pa = (A *)operator new(sizeof(A)); new(pa)A(5); (*pa).~A(); operator delete(pa); //free(pa); 使用free和使用operator delete效果一样 } int main() { test(); system("pause"); return 0; } 如下,是使用定位New和构造函数及析构函数来模拟new[]和delete[]操作符。 class A { private: int _a; int* _ptr; public: A(int a=1) :_a(a) , _ptr(NULL) { cout << "A()" << endl; _ptr = new int(3); } ~A() { cout << "~A()" << endl; delete _ptr; } }; void test() { int i = 0; A* pa = (A *)operator new(sizeof(A)* 5+4); (*(int *)pa) = 5; pa = (A*)((int *)pa + 1); for (i = 0; i < *((int*)pa-1); i++) { new(pa + i)A;//调用构造函数 } for (i = 0; i < *((int*)pa - 1); i++) { (pa+i)->~A(); } operator delete((int *)pa-1); } int main() { test(); system("pause"); return 0; }