抛出异常后释放失败的对象

时间:2014-07-14 14:54:43

标签: c++

在C ++中,当出现问题时,通常认为在构造函数中抛出异常是一种很好的策略。

但是,当失败的对象不是堆栈变量时,我对清理为失败对象分配的实际内存感到困惑。

考虑:

class Foo
{
    public:

    Foo()
    {
        throw std::runtime_error("Fail!");
    }
};

int main()
{
    Foo* f;
    f = new Foo();
}

如果我使用valgrind --leak-check=full运行此程序,则会报告:

=24981== 34 bytes in 1 blocks are possibly lost in loss record 2 of 3
==24981==    at 0x4C286E7: operator new(unsigned long) (vg_replace_malloc.c:287)
==24981==    by 0x4EEE998: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17)
==24981==    by 0x4EF0384: char* std::string::_S_construct<char const*>(char const*, char const*, std::allocator<char> const&, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17)
==24981==    by 0x4EF0462: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17)
==24981==    by 0x400D14: Foo::Foo()

...这向我表明,为Foo实例分配的内存从未被回收。当然,这是有道理的,因为在C ++中,new运算符实际上正在做两个事物。首先,它分配一个原始内存块(类似于malloc),然后通过调用构造函数Foo::Foo()来初始化原始内存。但由于Foo::Foo()抛出异常,所以分配的初始原始内存永远不会被回收。

那么,我该如何收回它?我无法捕获异常和delete对象,因为在抛出异常时我甚至没有指向对象的指针。

我唯一能想到的是使用placement new来分配和初始化。但是大多数C ++程序员甚至都不知道新的位置,所以我怀疑这个模糊的功能确实是寻找看似常见问题的方法。

那么,这里的正确策略是什么(假设堆栈分配不是一个选项)?

0 个答案:

没有答案