放置了重新分配功能的用途是什么?

时间:2015-07-19 06:58:30

标签: c++ class

12.5/4 [class.free]部分:

  

如果查找结果不明确或不可访问,或者如果   查找选择一个放置重新分配函数,该程序是   不良形成。

所以,例如,如果我们写:

class A
{
public:
    void* operator new  ( std::size_t count, std::size_t msg, std::size_t mmsg );
    void operator delete  ( void* ptr, std::size_t msg, std::size_t mmsg );
};

void* A::operator new  ( std::size_t sz, std::size_t msg, std::size_t mmsg ){
    std::printf("global op new called, message = %lu, %lu", msg, mmsg);
    return std::malloc(sz);
}

void A::operator delete  ( void* ptr, std::size_t msg, std::size_t mmsg ){
    std::printf("global op new called, message = %lu, %lu", msg, mmsg);
}

live example

放置释放函数永远不会被称为删除表达式的评估的一部分。因此,问一下它们的用途是合理的。我们只能通过手动调用operator[](void*, std::size_t, std::size_t)来调用它们,这是不方便的。

1 个答案:

答案 0 :(得分:5)

new - 表达式求值期间,当构造函数调用抛出时,将调用放置释放函数来清理。此时,传递给放置分配的信息仍然可用,并且可以再次传递给释放功能。稍后,在成功new - 表达式之后,该信息不可用,因此普通的释放函数由delete语句使用。

基本上,如果取消分配依赖于传递给放置分配函数的信息,则用户代码负责保留成功创建的对象的信息。另一种方法可能是指定C ++实现如何保留它,以便它可以遵守隐含的任何限制。但是这会带来复杂性,并且会违反“不要使用C ++的设计原则”。

Microsoft的MFC类框架曾经有一个错误,他们忘记提供一个放置释放函数来匹配他们在调试new中使用的放置分配函数,导致内存泄漏仅在调试版本中。愚蠢的。