【发布时间】:2019-03-20 15:12:21
【问题描述】:
我有一个其他人编写的可能不稳定的类,我必须创建该类的对象数组。我提到这个类是不稳定的,所以它可能偶尔会在默认构造函数中抛出异常。我无法访问源代码,只能访问已编译的二进制文件。
当我使用new 分配这些类型的对象的动态数组时,这些坏对象之一可能会引发异常。它抛出一个自定义异常,而不是std::bad_alloc。
无论如何,我需要让程序从异常中恢复并继续运行,尽管设置了一些错误标志等等。我认为我应该delete与数组关联的内存以防止内存泄漏。
我的理由是,如果类在数组中间某处构造元素时抛出异常,则该元素将无法正确构造,并且所有未来元素都将因异常而停止构造,但之前的元素自从抛出异常之前就已经正确构造了。我想知道,在catch (...) { } 中调用delete 是个好主意吗?我将如何解决这个内存泄漏?
Badclass* array = nullptr;
try {
array = new Badclass[10]; // May throw exceptions!
} catch (...) {
delete[] array;
array = nullptr;
// set error flags
}
这是我在记忆中形象化的方式。这是正确的吗?
array 0 1 2 3 4 5 6 7 8 9
___ __________________________________
| ---------->| :) | :) | :) | :) | :( | | | | | |
|___| |____|____|____|____|____|_|_|_|_|_|
【问题讨论】:
-
如果
new抛出,array从未被分配,所以delete对你来说没有任何意义。因此,即使异常来自构造其中一个元素,该语言也保证内存被释放。 -
@BoBTFish 问题是,
new没有投掷,Badclass::Badclass()是! -
尽管如此,
new是调用Badclass::Badclass()的东西,所以new永远不会完成 -
@Galaxy 没关系。如果请求的操作(分配和构造这一系列事物)抛出,那么与这两个活动相关的所有事情都会被退回。这包括分配和任何成功构造的对象(以及十个对象的数组请求满足五个,然后抛出,将按照构造的相反顺序为成功构造的五个触发析构函数,然后放弃内存本身并执行扔)。
-
它基于请求操作的成功。无法满足请求。因此,任何可能发生的事情都被撤消并抛出异常。这包括破坏已经构建的元素。并不是说任何人都会这样做(您可能只使用
std::vector并完成它,或者有充分的理由不这样做)。