栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++中的几种new和delete

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++中的几种new和delete

C++中的几种new和delete

在C语言中,使用malloc、calloc来分配堆上的空间,使用free来释放它们分配的空间; malloc、calloc、free都是库函数。
在C++中,使用new和delete,以及 new [] 和 delete [] 来分配和释放自由存储区(其实也就是堆)上的空间;它们都是操作符,属于语言的范畴。说到语言,往往就牵涉到编译器;而C++标准没有规定如何实现new/delete,但一般都是用malloc/delete来实现的。
本文讨论一下C++中的几种new以及delete的作用和实现。

1. C++中默认的new和delete

默认的new和delete,就是全局的new和delete, 也可称为全局的operator new/delete.
new 的功能: 为单个对象先分配一块内存,然后在其上调用构造函数进行初始化; 当申请不到内存的时候,抛出 std::bad_alloc 异常。
delete 的功能: 先调用析构函数,然后释放原先分配的内存。

对比malloc:

  • malloc 只是分配内存,而不会进行任何初始化操作;
  • malloc 申请内存失败的时候,返回NULL指针,不会抛出异常 (本来就是C语言)。

另外,如果是为多个对象申请空间和初始化以及释放,需使用 new [] 和 delete []. 语法如下:

int * pi = new int [5];  // 未初始化的数组
delete [] pi; 

int * pi2 = new int [5]();  // 每个数组元素初始化为0
delete [] pi2;

注意:

  • 上例中,第一种写法,对new出来的数组,是不做初始化的;
  • 而对第二种写法,即加了小括号的,则对每个数组元素都初始化为0.
2. 自定义 operator new/delete

可以为一个类自定义 operator new 和 operator delete;
但不能重载全局的 new 和 delete.

为一个类自定义 operator new/delete, 需要将它们声明为 static 函数,其形式如下:

static void * operator new (size_t size);  // size就是要申请的内存大小
static void operator delete(void * p);

注意:
如果自定义了new和delete,还要考虑自定义 new [] 和 delete [];
当然,也可以禁用 operator new [] 和 operator delete [].

自定义 operator new/delete 的工作原理为:

  • 全局的new: 先调用自定义的 operator new 申请内存;再由全局的new使用这块内存进行对象的初始化。
  • 当 operator new 申请不到内存的时候,应该抛出 std::bad_alloc 异常。
  • 全局的delete: 先调用析构函数,然后调用自定义的 operator delete 释放内存或将内存归还给内存池。
3. 自定义 operator new[] 和 delete[] 怎么实现?

这个问题其实就是问,为什么 delete[] 可以释放多个对象的内存呢?它怎么知道有多少个对象呢?
答案是,
在 operator new [] 的实现中,会在分配的内存中(一般是最前部)存储所分配的对象个数;
在 operator delete []的实现中,去读取这个地方,就知道释放多少个对象的内存了。

4. placement new

placement new 是在已经分配好的内存上构造对象。

语法是:

char * buf = (char *) malloc (sizeof(MyClass)); 
MyClass * p = new (buf) MyClass(...);

注意:
因为placement new 没有对应的delete,所以需要显式调用析构函数来释放资源:

p->~MyClass();

若是调用全局delete,则虽然析构函数会被调用,但全局delete也会去释放空间,而这块空间并不适合被自动释放,进而造成问题。
所以,这里只需手动调用析构函数即可,不必在此时释放空间。因为使用了placement new,所以释放空间的事情应交给开发者做。

(完)

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/296902.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号