我有一些(C ++)函数,每个函数包含多个调用,在堆上创建相同基本类型的类似数组。在这些函数的不同点,我可能需要抛出异常。跟踪哪些数组已被删除是一件痛苦的事情,而且非常容易出错,因此我在考虑将数组指针添加到Set<ArrType*>
,我可以在捕获异常时删除每个项目,例如这样:
try
{
set<ArrType*> sHeap;
ArrType* myArr = new ArrType[5];
sHeap.Add(myArr);
someExternalRoutine(myArr);
...
}
catch(CString s)
{
DeleteAllPointersInMyHeap(sHeap);
throw(s);
}
感觉有点像添加本轮,但我无法解决这样一个事实,即几个外部调用中的任何一个都可能抛出异常,我需要明确删除分配到该点的所有指针。
这只是愚蠢吗?我应该在外部调用周围添加较小的try-catch块吗?我最终还是会删除一些删除A的列表;删除B;删除D;在每一个之后...
答案 0 :(得分:19)
为什么不使用像boost::shared_array
这样的智能指针或使用堆栈分配的std::vector
?对于单个分配而不是数组分配,您可以使用boost::shared_ptr
。
这些为您实施RAII。即使您正在重新使用像RAII这样的概念,如果已经有一个满足您要求的具体实施,您仍然会重新发明轮子。
答案 1 :(得分:10)
您应该使用RAII技术。 您将销毁委托给您在堆栈上创建的另一个对象。
然后当该对象超出范围时,它将释放所有内容,无论它何时超出范围,即使有例外。
答案 2 :(得分:8)
而不是
try
{
set<ArrType*> sHeap;
ArrType* myArr = new ArrType[5];
sHeap.Add(myArr);
someExternalRoutine(myArr);
...
}
你只需要:
{
std::vector <ArrType> myArr(5);
someExternalRoutine(myArr);
}
没有捕获块。所有分配和解除分配(无论是否抛出异常)都将为您处理 - 这是RAII。
答案 3 :(得分:2)
您不必依赖垃圾收集。
你有std :: auto_ptr提供类似指针的语法并包装一个动态分配的对象。当它被破坏时,它会自动销毁它指向的对象。
你可以为数组实现类似的东西。
答案 4 :(得分:2)
看起来你正在思考它。
而不是使用try {} catch {}使用RAII 有几种方法可以查看注释(似乎都是有效的)。
选项1:
如果您只需要一个固定的(或扩展的ArrType集)
寿命在函数结束时结束的地方
std::vector<ArrType>
选项2:
如果需要多个ArrType数组
寿命在函数结束时结束的地方
boost::ptr_vector<ArrType>
当对象具有更长的使用寿命时,这也允许您从ptr_vector中删除数组。