C++动态内存管理

    xiaoxiao2021-03-25  65

    众所周知,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; }
    转载请注明原文地址: https://ju.6miu.com/read-36343.html

    最新回复(0)