我遇到了一个try-catch情况的问题,这里是代码(这很简单):
struct Something
{
int A, B, C;
Something()
{
A = B = C = 0;
}
~Something()
{
cout << "Destructor " << endl;
}
};
int main()
{
Something * s = new Something;
//Something * s = new Something[5];
try
{
delete[] s;
}
catch(exception& e)
{
delete s;
}
return 0;
}
我打算做的是首先尝试将指针删除为数组,如果失败,则进行简单的删除。
所以,当我第一次尝试使用'Something'(如在注释行中)的数组时,itr工作得很好。但是,当我现在尝试它时,我得到了一个可怕的错误。
有什么想法吗?
答案 0 :(得分:7)
你想做的事既不是合法的C ++也不合理。
使用new
的分配后必须删除delete
,new[]
分配delete[]
;这必须就是这样,其他一切都是未定义的行为。
您无法“尝试查看您是否编写了正确的代码”。异常表示异常运行时行为,但您的错误是一个静态的编译时错误,无法处理,但必须已修复。
但是,代码中永远不应该有不知道给定指针的含义!由于语言是静态类型,因此您原则上应始终了解所涉及的类型。如果你想传递对象(可能是多态的),那么任何需要动态分配的东西都应该包含在自己的经理类中(比如shared_ptr
或unique_ptr
)。
答案 1 :(得分:4)
将指针删除为数组(反之亦然)是不正确的,未定义的。它不会抛出异常。
您应该考虑RAII。例如,创建一个包含指针作为成员的类。构造函数分配内存,析构函数删除它。
然后你有几个选择:
(1)有两个构造函数,一个用于单个项目,另一个用于数组。在类中放置一个布尔值,用于指示指针是指向一个项还是数组,并在销毁时检查它并调用相应的删除函数。
(2)使您的类成为一个模板类,它接受一个布尔模板参数并在编译时解析该选择。
答案 2 :(得分:0)
所以我的c ++技能很生疏,但在你调用new []的地方调用了delete []。你没有在你的例子中调用new []。
答案 3 :(得分:0)
您完全误解了try
/ catch
的语义。他们没有捕获错误,他们捕获例外。如果您自己抛出异常或者做一些保证抛出异常的事情,您只能依赖于创建的异常。在分配有delete
的指针上调用new[]
并不能保证抛出异常,事实上,它不能保证做任何特定的事情。