【Effective C++】读书笔记 条款52:写了placement new 也要写placement delete

定制new 和 delete

条款52:写了placement new 也要写placement delete

1. new 操作中的内存泄漏

有如下一个new操作

A *pb = new A;  //A是一个自定义class类型

我们知道,对于一个new操作,一共有如下步骤,
1. 调用operator new请求分配内存。
2. 调用A的构造函数进行构造。
3. 返回指针

假设第一步已经操作成功,但是在B的构造函数被调用的时候却发生了异常,所以为了防止内存泄漏,步骤一中的内存分配必须取消来恢复原状。但是此时pb并未被赋值相应的值,客户代码是没有能力来进行内存释放的。所以这个善后工作就交给了C++运行期系统。C++运行期系统就会调用与operator new相应的operator delete版本来释放内存。这样就保证了不会造成潜在的内存分配。

2. 定义与placement new 相对应的 placement delete 来防止内存泄漏

placement new 和 placement delete

先解释一个术语,placement new。

我们知道,对于一个operator new,其第一个参数一定是size_t,但是我们想定义一个新的operator new,它所接受的参数就可能除了size_t之外还有其他类型。这就是placement new的一个含义。其是指的是,接受任意额外实参的operator new。

除此之外,对于C++自身而言,它还提供了一个版本的operaotr new。

//C++98版本 placement
void* operator new (std::size_t size, void* ptr) throw()

//C++11版本 placement
void* operator new (std::size_t size, void* ptr) noexcept;

这个版本的operator new 接受一个 void *类型的额外参数,函数功能只是返回这个指针地址,来指示new操作中第二个步骤的构造函数在此指针所指地址上进行构造对象。这个版本的operator new也被称为 placement new。事实上,这个术语的名称也是来自于此。

所以人们谈到,placement new的时候,大多数是提到的指唯一额外实参是 *的operator new,少数时候是指的接受任意额外实参的operator new。

与此术语相对应的有placement delete。同样有两个含义,一个是C++提供的额外接受一个void *的operator delete。


//C++98 placement (3)   
void operator delete (void* ptr, void* voidptr2) throw();

//C++11 placement (3)   
void operator delete (voi

你可能感兴趣的:(读书笔记,effective-c++,c++,new,delete,内存泄露)