C++ ——内存管理
文章目录
一、C++ 内存管理方式
C 语言的内存管理方式在 C++ 中可以继续使用,但有些地方就无能为力,而且使用起来相对繁琐一些,因此,C++ 又提出了自己的内存管理方式:通过 new 和 delete 操作符进行动态内存管理。
1.1 new/delete 操作内置类型
voidtest(){// 动态申请一个 int 类型的空间int* ptr1 =newint;// 动态申请一个 int 类型的空间并初始化为 10int* ptr2 =newint(10);// 动态申请 10 个 int 类型的空间int* ptr3 =newint[10];delete ptr1;delete ptr2;delete[] ptr3;}1.2 new/delete 操作自定义类型
在操作自定义类型的空间时,new 会调用构造函数,delete 会调用析构函数,而 malloc 和 free 不会。
#include<iostream>usingnamespace std;classA{public:A(int a =0):_a(a){ cout <<"A():"<<this<< endl;}~A(){ cout <<"~A():"<<this<< endl;}private:int _a;};intmain(){// new/delete 调用构造函数/析构函数 A* p1 =(A*)malloc(sizeof(A)); A* p2 =newA(1);// 调用构造函数free(p1);delete p2;// 调用析构函数// 内置类型几乎一样int* p3 =(int*)malloc(sizeof(int));int* p4 =newint;free(p3);delete p4; A* p5 =(int*)malloc(sizeof(A)*10); A* p6 =new A[10];free(p5);delete[] p6;return0;}二、operator new 与 operator delete 函数
new 和 delete 是用户进行动态内存申请和释放的操作符,operator new 和 operator delete 是系统提供的全局函数,new 在底层调用 operator new 全局函数来申请空间,delete 在底层通过operator delete全局函数来释放空间。
三、new 和 delete 的实现原理
3.1 内置类型
如果申请的是内置类型的空间,new 和 malloc,delete 和 free 基本类似,不同的地方是:new/delete 申请和释放的是单个元素的元素空间,new[] 和 delete[] 申请的是连续空间,而且 new 在申请空间失败时会抛出异常,malloc 会返回 NULL。
3.2 自定义类型
- new 的原理
- 调用 operator new 函数申请空间
- 在申请的空间上执行构造函数,完成对象的构造
- delete 的原理
- 在空间上执行析构函数,完成对象中资源的清理工作
- 调用 operator delete 函数释放对象的空间
- new T[N] 的原理
- 调用 operator new[] 函数,在 operator new[] 中实际调用 operator new 函数完成 N 个对象空间的申请
- 在申请的空间上执行 N 次构造函数
- ** delete[] 的原理**
- 在释放的对象空间上执行 N 次析构函数,完成 N 个对象中资源的清理
- 调用 operator delete[] 释放空间,实际在 operator delete[] 中调用 operator delete 来释放空间
四、malloc/free 和 new/delete 的区别
malloc/free 和 new/delete 的共同点是:都是从堆上申请空间,并且需要用户手动释放。其不同点见如下表格:
| malloc/free | new/delete |
|---|---|
| 函数 | 操作符 |
| 申请的空间不会初始化 | 可以初始化 |
| 需要手动计算控价大小并传递 | 跟上类型即可, 若为多个对象在[]中指定 |
| malloc返回类型为void*使用须强转 | new后跟的是空间的类型 |
| malloc申请空间失败返回NULL必须判空 | new不需要判空但需要捕获异常 |
| 自定义类型对象时只会开辟空间 | 申请自定义类型对象时会调用构造函数和析构函数 |
总结
本文介绍了 C++ 中内存管理的操作符 new 和 delete,并详细介绍了他们的使用方法和基本原理同时与 C 中的 malloc 函数和 free 函数做对比,深化理解了二者的不同,便于更好的使用二者。