C++动态内存管理

来源:互联网 发布:java免费下载 编辑:程序博客网 时间:2024/06/04 23:18

众所周知,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;}


0 0