我有一个别人写的潜在不稳定的类,我不得不创建该类的对象数组.我提到该类是不稳定的,因此它可能偶尔会在默认构造函数中抛出异常.我无权访问源代码,只能访问已编译的二进制文件.
当我使用这些类型的对象分配动态数组时new,这些坏对象之一可能会抛出异常.它抛出一个自定义异常,而不是std::bad_alloc.无论如何,我需要让程序从异常中恢复并继续使用,尽管设置了一些错误标志,什么不是.我认为我应该delete与数组关联的内存,以防止内存泄漏.
我的理由是,如果类抛出在数组中间某处构造元素的异常,那么该元素将无法正确构造,并且所有未来元素将被异常停止构造,但之前的元素将是因为在抛出异常之前发生了这种情况.我想知道,是不是一个好主意,打电话delete的catch (...) { }?我该如何解决这个内存泄漏?
Badclass* array = nullptr;
try {
array = new Badclass[10]; // May throw exceptions!
} catch (...) {
delete[] array;
array = nullptr;
// set error flags
}
Run Code Online (Sandbox Code Playgroud)
这是我在内存中可视化的方式.它是否正确?
array 0 1 2 3 4 5 6 7 8 9
___ __________________________________
| ---------->| :) | :) | :) | :) | :( | | | | | |
|___| |____|____|____|____|____|_|_|_|_|_|
Run Code Online (Sandbox Code Playgroud) 我知道从析构函数中抛出异常是不安全的,但是从构造函数中抛出异常是不安全的?
例如,全局声明的对象会发生什么?使用gcc进行快速测试,我得到了中止,是否始终保证?你会用什么解决方案来迎合这种情况?
是否有任何情况下构造函数可以抛出异常而不是留下我们期望的东西.
编辑:我想我应该补充一点,我试图理解在什么情况下我可以获得资源泄漏.看起来明智的做法是手动释放我们在抛出异常之前通过构造获得的资源.我从来不需要在今天之前在构造函数中抛出异常,所以试图理解是否存在任何陷阱.
即这也安全吗?
class P{
public:
P() {
// do stuff...
if (error)
throw exception
}
}
dostuff(P *p){
// do something with P
}
...
try {
dostuff(new P())
} catch(exception) {
}
Run Code Online (Sandbox Code Playgroud)
分配给对象P的内存是否会被释放?
EDIT2:忘了提到在这种特殊情况下,dostuff将对P的引用存储在输出队列中.P实际上是一条消息,dostuff接收消息,将其路由到适当的输出队列并发送它.基本上,一旦dostuff持有它,它会在后来的dostuff内部释放.我想我想把一个autoptr放在P周围并在dostuff后调用autoptr上的释放以防止内存泄漏,这是正确的吗?
我正在与一些同事讨论在动态分配的类中抛出异常时会发生什么.我知道malloc被调用,然后是类的构造函数.构造函数永远不会返回,所以会发生什么malloc?
请考虑以下示例:
class B
{
public:
B()
{
cout << "B::B()" << endl;
throw "B::exception";
}
~B()
{
cout << "B::~B()" << endl;
}
};
void main()
{
B *o = 0;
try
{
o = new B;
}
catch(const char *)
{
cout << "ouch!" << endl;
}
}
Run Code Online (Sandbox Code Playgroud)
malloced内存会发生什么o,它会泄漏吗?CRT是否捕获构造函数的异常并释放内存?
干杯!
丰富
Early today I discovered function try-catch blocks (from here in fact) and then went on a bit of a research spree - apparently they're main use is it catch exceptions throw in by a constructor initialiser list.
无论如何,这让我想到了失败的构造函数,我已经到了一个我需要一点澄清的阶段.这只是我试图了解更多关于语言的内容,所以我没有一个实际的例子,但是这里......
鉴于此示例代码:
class A
{
private:
B b
C *c; //classes B, C & D omitted for brevity as not really relevant
D d;
public
A(int x, int y, int z)
};
A::A(int x, int y, int z)
try
: b( …Run Code Online (Sandbox Code Playgroud) 感谢所有的回复.
我重新格式化了我的问题,以便在包含类的构造函数抛出异常之后理解成员指针的状态
我的示例类:)
class Foo
{
public:
Foo()
{
int error = 0;
p = new Fred;
throw error; // Force throw , trying to understand what will happen to p
}
~Foo()
{
if (p)
{
delete p;
p = 0;
}
}
private:
Fred* p;
};
int main()
{
try
{
Foo* lptr = new Foo;
}
catch (...)
{}
}
Run Code Online (Sandbox Code Playgroud)
类foo的consturctor会因某些随机原因而抛出异常.我知道foo的desturctor永远不会被调用,但在这种情况下,p的析构函数会被调用吗?
将p作为增强智能指针而不是指向fred的原始指针有什么不同.
谢谢.
根据valgrind下面的代码并没有包含内存泄漏:
#include <memory>
#include <stdexcept>
namespace {
class Foo {
public:
Foo();
};
Foo::Foo() { throw std::runtime_error("This is an error"); }
} // anonymous namespace
int main(int argc, char* argv[]) {
try {
new Foo();
} catch (const std::exception& aError) {
return -1;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
确实.结果valgrind --leak-check=full是:
==25913== Memcheck, a memory error detector
==25913== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==25913== Using Valgrind-3.13.0 and LibVEX; rerun with …Run Code Online (Sandbox Code Playgroud)