【C++笔记】C++内存管理

【C++笔记】C++内存管理

  • 一、C++中动态内存申请的方式
  • 二、new和delete的实现原理
    • 2.1、operator new和operator delete函数

一、C++中动态内存申请的方式

在C语言中我们需要动态申请空间的时候我们通常都是用malloc函数,但是malloc函数对自定义类型是没什么问题的,但是对于自定义类型就不那么适用了。
因为malloc函数负责的只是开空间,并不会去调用类的构造函数:
【C++笔记】C++内存管理_第1张图片
如果是像栈这样的有额外申请空间的类,没有初始化这将是一件很危险的事情,因为我们后面向栈中插入数据的时候就一定会出错(野指针)。

所以为了解决这样的问题,C++就设计了套新的动态内存申请的方案,即new和delete。

在C语言中使用malloc动态申请的空间不仅需要我们强转成指定的指针类型而且还需要我们手动计算空间的大小:
【C++笔记】C++内存管理_第2张图片
但在C++中使用new,我们不需要强转而且只需要给出数据的个数即可:
【C++笔记】C++内存管理_第3张图片
如果只是申请一个int空间,那就不用再int后面加[]:
【C++笔记】C++内存管理_第4张图片
并且对于自定义类型,new也会去自动调用构造函数:
【C++笔记】C++内存管理_第5张图片
像C语言一样,动态申请的空间默认不会去初始化:
【C++笔记】C++内存管理_第6张图片
但C++支持在动态申请的同时去给空间初始化:
【C++笔记】C++内存管理_第7张图片
而且也像C语言一样未指定初始化的数据就是用0来做默认值。

如果只是申请一个空间就是用括号:
【C++笔记】C++内存管理_第8张图片
这其实也就是像自定义类型一样去调用构造函数:
【C++笔记】C++内存管理_第9张图片
而如果是多个对象的话,我们就可以用到匿名对象或饮食类型转换:
【C++笔记】C++内存管理_第10张图片
而且从结果来看,如果没有指定构造的话就回去调用是用默认构造的缺省值。

说完new,我们再来说delete,对于内置类型来说new和delete与malloc和free几乎没什么区别,我们主要来说说自定义类型:
【C++笔记】C++内存管理_第11张图片
对于自定义类型,delete会去调用析构函数,这是free函数所欠缺的。

如果只是单个对象,我们我们就不用加[]:
【C++笔记】C++内存管理_第12张图片

二、new和delete的实现原理

2.1、operator new和operator delete函数

其实new和delete的底层还是使用malloc和free实现的,但他们并不能直接调用malloc和free。因为使用new如果空间申请失败的话是要抛异常的,并且delete要去调用析构函数。
而malloc如果空间申请失败的话就直接返回0了(空指针),free也只是单纯的释放空间并不会去调用析构函数。
所以C++需要对malloc和free进行“封装”,封装成两个函数:operator new和operator delete。

我们现在来看看库中的operator new和operator delete的实现:
【C++笔记】C++内存管理_第13张图片
【C++笔记】C++内存管理_第14张图片
我们会发现其实里面还是用到了malloc和free的,至于其他的那些看不懂的都是跟异常现相关的。我们现在可以不理会。

你可能感兴趣的:(C++之路,c++,笔记,开发语言,c语言)