构造函数异常和内存泄漏

Exception in constructor and memory leaks

我有一个 class 可以分配内存并可以在构造函数中抛出异常,例如:

class A
{
    int *x;
public:
    A () { x = new int; throw 0;}
    ~A () { delete x; }
};

我想动态创建这样的对象 class。我应该怎么做才能防止内存泄漏? 我尝试在 try 块中创建对象并在 catch 块中删除对象,但地址清理器已报告 SEGV on unknown address.

int main()
{
    A *a;
    try { a = new A; }
    catch(int) { delete a; } // AddressSanitizer: SEGV on unknown address
}

在不删除对象的情况下,我们(显然)存在内存泄漏,泄漏清理程序报告了这一点。

int main()
{
    A *a;
    try { a = new A; }
    catch(int) {} // LeakSanitizer: detected memory leaks
}

然而,如果没有 try - catch,两种消毒剂都是无声的。我想知道是否仍然存在内存泄漏,如果是,如何解决?

int main()
{
    A *a;
    a = new A; // terminate called after throwing an instance of 'int'
}

UPD:是的,我知道共享指针。我的问题主要是关于最后一个案例(没有处理异常)。为什么消毒剂是无声的?只是泄漏消毒剂流还是真的没有泄漏?

以下部分代码无效:

int main()
{
    A *a;
    try { a = new A; }
    catch(int) { delete a; } // AddressSanitizer: SEGV on unknown address
}

如果在 运行 new A 时抛出异常,那么在异常发生之前 A 设法构建的任何东西都会被破坏。此外,a 的内存会自动释放。

在上面的例子中,当抛出异常时,指针a甚至没有被赋值一次,处于未初始化状态。

解决泄漏的最安全方法是使用 std::unique_ptr

class A
{
    std::unique_ptr<int> x;
public:
    A (): x(std::make_unique<int>()} { throw 0;}
    A(A&&) = default;
    A& operator=(A&&) = default;
    A(const A &); // do something smart here
    A& operator=(const A &); // do something smart here
    ~A () { }
};

使用 unique_ptr 在异常之前构造的任何内容都将被自动释放。