【问题标题】:Exception in constructor and memory leaks构造函数异常和内存泄漏
【发布时间】:2019-08-19 07:05:08
【问题描述】:

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

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

我想动态创建此类的对象。我应该怎么做才能防止内存泄漏? 我尝试在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:是的,我知道共享指针。我的问题主要是关于最后一种情况(不处理异常)。为什么消毒剂无声?它只是泄漏消毒剂流动还是真的没有泄漏?

【问题讨论】:

标签: c++ exception memory-leaks address-sanitizer


【解决方案1】:

以下部分代码无效:

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 在异常之前构造的任何东西都将被自动释放。

【讨论】:

    猜你喜欢
    • 2018-11-18
    • 2021-06-17
    • 2013-01-12
    • 2020-11-02
    • 2021-07-07
    • 2014-11-15
    • 1970-01-01
    • 2015-08-29
    • 1970-01-01
    相关资源
    最近更新 更多