c++ new和delete简单探索
1. new 和 delete 工作步骤
- new:
- 使用标准库函数
operator new
或者operator new[]
在堆内存中分配出一块足够大的内存 - 调用相应的构造函数构造出对象并赋初值,对象安排在步骤1的内存上(
定位new
) - 返回指向这块内存的指针
- delete:
- 调用对象的析构函数
- 调用标准库函数
operator delete
或者operator delete[]
释放空间。
在new分配内存失败后会调用new-handler处理:new_handler介绍
2. 用户可以重载operator new来实现自己的new方式
// 默认是static的
void* operator new ( std::size_t count );
void* operator new[]( std::size_t count );
- 重载
operator new
可以分为全局作用域和类作用域- 重载类作用域的
operator new
, static属性
- 重载类作用域的
class Base {
public:
Base() {
cout << "Base()" << endl;
}
~Base() {
cout << "~Base()" << endl;
}
void * operator new(size_t p) { // 在构造函数的时候调用,默认是static的。
cout << "operator new" << endl;
return ::operator new(p); // 调用全局的operator new
}
static void operator delete(void *p) { // 在构造函数的时候调用,默认是static的。
cout << "operator delete" << endl;
return ::operator delete(p); // 调用全局的operator delete
}
};
int main()
{
Base *p = new Base();
delete p;
return 0;
}
知识点:
operator new
一段长度为0
的空间是允许的,内部处理逻辑可能将size
置位1
operator delete
一个null
指针是安全的,内部对传入的参数进行判null
处理- 基类重写了
operator new
,子类在new
的时候会调用基类的operator new
,分配出来的大小并不是子类所需的内存大小
3. placement new、placement delete
placement new
:operator new
接收的参数除了一定会有的那个size_t
之外还有其他的参数,称为placement new
,通常placement new
会接收一个指针指向对象构造的地址。(new
对象的时候也可以认为是在指定地点的placement new
)
void * operator new (std::size_t, void *pMemory) throw();
placement new
和placement delete
要成对使用, 当内存分配成功,构造执行失败时,需要对应的placement delete
来释放分配的空间。- 当自定义了
operator new
和operator delete
后,也就意味着覆盖了global operator new、delete
static void *operator new(std::size_t size, std::ostream &logStream) throw(std::bad_alloc);
static void operator delete(void *pMemory, std::ostream &logStream)throw();
ClassA *ca = new (std::cerr) ClassA();
// 以下是默认的operator new/delete
void *operator new(std::size_t) throw(std::bad_alloc); // normal new
void operator delete(void *pMemory) throw();
void *operator new(std::size_t, void *) throw(); // placement new
void operator delete(void *pMemory, void *) throw();
void *operator new(std::size_t, const std::nothrow_t&) throw(); // nothrow new
void operator delete(void *pMemory, const std::nothrow_t&) throw();
- new/operator new/placement new 对比
new:
调用了operator new来分配内存,然后调用了构造函数在分配的内存上构造对象
operator new:
在指定或者默认的空间上分配指定大小的内存,当内存不足时调用new-handler来处理,如果new-handler
为null
,抛出bad_alloc
异常
placement new:
定位new,非正常形式的operator new
,在指定的位置上分配内存。