重载new和delete控制内存分配教程
首先要明白:
当new一个对象的时候程序实际上经过了三个步骤:
- new表达式调用operator new或者operator new[] 函数来分配一块内存。
- 编译器运行构造函数构造并初始化对象。
- 返回一个指向对象的指针。
当delete一个对象的时候:
- 对对象执行析构函数
- 表达式调用operator delete或operator delete[]释放内存。
当我们重载new和delete的时候,实际上是重载operator new,operator delete函数。在operator函数中用malloc和free函数执行分配内存与释放内存操作。
operator new和operator delete接口:
//这些版本可能抛出异常
- void* operator new ( std::size\_t count );
- void* operator new[]( std::size\_t count );
- void operator delete ( void* ptr ) noexcept;
- void operator delete[]( void* ptr ) noexcept;
//这些版本承诺不会抛出异常
void* operator new ( std::size\_t count, const std::nothrow\_t& tag) noexcept;
void* operator new[]( std::size\_t count, const std::nothrow\_t& tag);
void operator delete ( void* ptr, const std::nothrow\_t& tag ) noexcept;
void operator delete[]( void* ptr, const std::nothrow\_t& tag ) noexcept;
使用定位new在operator new分配内存空间构造对象。(对于allocator分配的内存,可用construct构造对象)
定位new的四种形式:
- new (place\_address) type
- new (place\_address) type (initializers)
- new (place\_address) type [size]
- new (place\_address) type [size] {braced initializer list}
当采用第一,三种形式,仅通过一个地址进行调用时,定位new采用operator new(size\_t, void*)”分配”它的内存(该operator new不可自定义,不分配内存,简单地返回指针实参,所以前面的分配是打引号),然后new表达式在指定地址初始化对象。
当采用第二,四种形式,用给定初始值列表初始化place\_address指定内存。
定位new和construct还有一个区别:传给construct的指针必须指向同一个allocator,但传给定位new的指针无须是operator new分配的内存