new/delete 与 operator new/delete详解

new有三种调用形式

//throwing (1)	
void* operator new (std::size_t size);
//nothrow (2)	
void* operator new (std::size_t size, const std::nothrow_t& nothrow_value) noexcept;
//placement (3)	
void* operator new (std::size_t size, void* ptr) noexcept;

(1) throwing allocation
分配 size bytes的储存空间,适当对齐以表示该大小的任何对象,返回一个指向这片储存块最前面一位的非空指针。若失败,返回一个 bad_alloc 异常。
(2) nothrow allocation
同1,区别在于失败后返回一个空指针而非bad_alloc异常
(3) placement
仅仅返回ptr。没有储存空间被分配。
请注意:本函数被一个新的表达式调用时,合适的初始化函数会被调用,如被类对象对用,本函数会调用类的默认构造函数。

delelte有五种调用形式(c++14)

//ordinary (1)	
void operator delete (void* ptr) noexcept;
//nothrow (2)	
void operator delete (void* ptr, const std::nothrow_t& nothrow_constant) noexcept;
//placement (3)	
void operator delete (void* ptr, void* voidptr2) noexcept;
//with size (4)	
void operator delete (void* ptr, std::size_t size) noexcept;
//nothrow with size (5)	
void operator delete (void* ptr, std::size_t size, const std::nothrow_t& nothrow_constant) noexcept;

(1) ordinary delete
析构由ptr指针(若非空,空的话异常)指向的空间,释放有之前调用new开辟的内存空间。并把该指针置为无效。
(2) nothrow delete
同1,默认调用的是1,声明了方便重载。对应new的(2)
(3) placement delete
啥也不干。对应new的(3)
(4) (5) with size
与(1) (2) 相似,它们为自定义实现提供了一个优化点:使用与调用相应分配函数相同的size参数来调用它们。

new和delete具有的特性

  • 全局性:在全局命名空间中定义,并不是在std命名空间中
  • 隐式的:(1)(2)调用方法在每一个c++的翻译单元中都已经被隐式声明,不需要而外include new 头文件
  • 可替换的:(1)(2)是可以被替换或重载的
  • set_new_handler可以修改1,2的异常函数

operator new/delete 与new/delete 区别

operator new可以被显式调用,但在c++中,new是一个有特定表现的操作:
一个表达是调用new,将首先调用函数 operator new,调用参数取决于表达式里的类型大小。
然后调用该类型的构造函数。最后将返回的指针转换成对应类型的指针。

简单来说,就是new里面内置调用了operator new开辟空间分配内存,并把这片内存初始化为对应的类型(通过调用对应的构造函数),再返回对应类型的指针。operator new和operator delete这两个全局函数相当于c的malloc和free

理解了new,delelte是对应的
operator delete可以被显式调用,但在c++中,delete是一个有特定表现的操作:
delete先调用对应类型的析构函数,然后调用operator delete。

实例

// operator new example
#include <iostream>     // std::cout
#include <new>          // ::operator new

struct MyClass {
  int data[100];
  MyClass() {std::cout << "constructed [" << this << "]\n";}
};

int main () {

  std::cout << "1: ";
  MyClass * p1 = new MyClass;
      // allocates memory by calling: operator new (sizeof(MyClass))
      // and then constructs an object at the newly allocated space

  std::cout << "2: ";
  MyClass * p2 = new (std::nothrow) MyClass;
      // allocates memory by calling: operator new (sizeof(MyClass),std::nothrow)
      // and then constructs an object at the newly allocated space

  std::cout << "3: ";
  new (p2) MyClass;
      // does not allocate memory -- calls: operator new (sizeof(MyClass),p2)
      // but constructs an object at p2

  // Notice though that calling this function directly does not construct an object:
  std::cout << "4: ";
  MyClass * p3 = (MyClass*) ::operator new (sizeof(MyClass));
      // allocates memory by calling: operator new (sizeof(MyClass))
      // but does not call MyClass's constructor

  delete p1;
  delete p2;
  delete p3;

  return 0;
}

输出结果(内存分配不同,后面的数据不同)

1: constructed [0x8f0f70]
2: constructed [0x8f23a8]
3: constructed [0x8f23a8]
4: 

参考网页

cpp官网_new
cpp官网_delete

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值