C++自制心得——动态内存管理
1. new与delete
我们来回顾一下C语言的内存管理函数
显然,malloc全家桶的缺点很明显,又要强转,还要手动计算申请空间大小,而且更糟的是,它们不适配自定义类型
如果我们用malloc开空间,其中的自定义类型是无法初始化的,因为malloc根本不认识构造函数,在这种情况下,malloc完全没法用,必须用一种新方式申请内存
free函数虽然写起来简单,但是它也不能很好的适配自定义类型
幸好析构函数可以直接调用,不然这个对象s很难释放
正因原装函数过于臃肿,不支持自定义类型,所以C++提供了新的内存管理方式,也就是new与delete操作符

new与delete的使用方法如下:
1. 沿袭C语言的传统,申请的空间需要用对应指针变量维护
2. 申请空间分为单体申请与群体申请,释放空间同理
3. 申请多个对象时,其初始化逻辑沿袭数组

4. 请确保对象的申请与释放由对应的函数完成,否则视为未定义行为
用malloc全家桶申请的空间请用free释放,用new申请的空间请用delete释放,用new[]申请的空间请用delete[]释放,如果不这么做,出现什么稀奇古怪的错误都是正常的
5. new与delete在申请或释放空间时会自动调用构造函数或析构函数
以顺序表举例

6. new失败后不会返回nullptr而是抛异常
2. new和delete的底层机制
new和delete是用户进行动态内存申请和释放的操作符,operator new和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。(这两个函数也分单体群体)
下面是某大佬从编译器里扒出来的operator new&delete源码
(我也不知道下面的函数是怎么运作的)
好吧,虽然看不懂代码在干什么,不过malloc和free我们还是认识的,显然operator new和operator delete(这两函数不是new与delete的重载函数,我也不知道为什么设计人员要这么命名)是C的内存管理函数的封装形式
你也可以显式调用这两个函数(你为什么要这么做)
用法与malloc和free基本保持一致,不过申请失败不会返回nullptr而是抛异常

new & delete自动调用构造或析构的功能在operator new & delete外实现,所以此处的s1,s2并未初始化

异常是C++引入的新错误处理机制,大大简化了错误处理的逻辑
这就是一个简单的异常处理程序,出现异常就会输出异常信息

在try代码块中执行的代码一旦出现异常就会引起执行流跳跃,直接跳转到catch代码块,不会执行剩下的指令,这点与goto颇为相似。如果异常语句不在try代码块中或者没有写异常回收机制,程序会挂掉
(彻底理解异常需要继承多态前置,本专栏只给出基本写法)

现在我们可以总结new与delete的工作原理了
1. 对于内置类型
new和malloc,delete和free基本类似,不同的地方是: new/delete申请和释放的是单个元素的空间,new[]和delete[]申请的是连续空间,而且new在申请空间失败时会抛异常,malloc会返回nullptr。
2. 对于自定义类型
new的原理
1. 调用operator new函数申请空间
2. 在申请的空间上执行构造函数,完成对象的构造
delete的原理
1. 在空间上执行析构函数,完成对象中资源的清理工作
2. 调用operator delete函数释放对象的空间
new Type[N]的原理
1. 调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对象空间的申请
2. 在申请的空间上执行N次构造函数
delete[]的原理
1. 在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理
2. 调用operator delete[]释放空间,实际在operator delete[]中调用operator delete来释放空间
3. 定位new
定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象。
使用格式: new (place_address) type或者new (place_address) type(initializer-list) place_address必须是一个指针,initializer-list是类型的初始化列表
借助于定位new,我们可以实现构造函数的显式调用
一般情况下,定位new没有使用必要,在实际中一般是配合内存池使用。因为内存池分配出的内存没有初始化,所以如果是自定义类型的对象,需要使用new的定义表达式显式调用构造函数进行初始化。

下一节我们讲模板初步,敬请期待