Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在我的函数中重新创建一个小型垃圾收集系统,我疯了吗?_C++_Garbage Collection - Fatal编程技术网

C++ 在我的函数中重新创建一个小型垃圾收集系统,我疯了吗?

C++ 在我的函数中重新创建一个小型垃圾收集系统,我疯了吗?,c++,garbage-collection,C++,Garbage Collection,我有一些(C++)函数,每个函数都包含几个在堆上创建相同基本类型的类似数组的调用。在这些函数的不同点上,我可能需要抛出一个异常。跟踪哪些数组已被删除是一件痛苦的事情,而且很容易出错,因此我考虑只将数组指针添加到集合,在捕获异常时,我可以删除其中的每一项,如下所示: try { set<ArrType*> sHeap; ArrType* myArr = new ArrType[5]; sHeap.Add(myArr); someExternalRoutine(m

我有一些(C++)函数,每个函数都包含几个在堆上创建相同基本类型的类似数组的调用。在这些函数的不同点上,我可能需要抛出一个异常。跟踪哪些数组已被删除是一件痛苦的事情,而且很容易出错,因此我考虑只将数组指针添加到
集合
,在捕获异常时,我可以删除其中的每一项,如下所示:

try
{
   set<ArrType*> sHeap;
   ArrType* myArr = new ArrType[5];
   sHeap.Add(myArr);
   someExternalRoutine(myArr);
   ...
} 
catch(CString s)
{
   DeleteAllPointersInMyHeap(sHeap);
   throw(s);
}
试试看
{
设棚;
ArrType*myArr=新的ArrType[5];
添加(myArr);
一些外部程序(myArr);
...
} 
捕获(CSTS)
{
DeleteAllPointersInMyHeap(sHeap);
投掷;
}
这感觉有点像是添加了epicycles,但我无法回避这样一个事实,即几个外部调用中的任何一个都可能引发异常,我需要明确地删除分配到该点的所有指针


这只是愚蠢吗?我是否应该在外部调用周围添加较小的try-catch块?我最终还是会得到一个小小的删除列表;删除B;删除D;在每一次之后…

你应该使用RAII技术。 将销毁委托给在堆栈上创建的另一个对象


然后,当该对象超出范围时,它将取消分配所有内容,无论它何时超出范围,即使存在异常。

为什么不使用智能指针或使用分配的堆栈?对于单个分配而不是数组分配,可以使用


这些是为您实现的。即使您使用的是像RAII这样的概念,如果已经有了满足您需求的具体实现,您仍然在重新设计轮子。

您不必依赖垃圾收集

您有std::auto_ptr,它提供类似指针的语法并包装动态分配的对象。销毁时,它会自动销毁指向的对象

您可以为阵列实现类似的功能。

而不是

try
{
   set<ArrType*> sHeap;
   ArrType* myArr = new ArrType[5];
   sHeap.Add(myArr);
   someExternalRoutine(myArr);
   ...
} 
试试看
{
设棚;
ArrType*myArr=新的ArrType[5];
添加(myArr);
一些外部程序(myArr);
...
} 
你只需要:

{
   std::vector <ArrType> myArr(5);
   someExternalRoutine(myArr);
}
{
std::载体myArr(5);
一些外部程序(myArr);
}

没有挡块。所有分配和解除分配(无论是否引发异常)都将为您处理-这是RAII。

看起来您想得太多了

不要使用try{}catch{}而要使用RAII。
有几种方法可以通过查看评论来做到这一点(所有方法似乎都是有效的)

选项1:
如果您只需要单个固定(或扩展)类型集。
寿命在函数结束时结束

std::vector<ArrType>
boost::ptr_vector<ArrType> 
std::vector 选项2:
如果您需要多个ArrType数组 寿命在函数结束时结束

std::vector<ArrType>
boost::ptr_vector<ArrType> 
boost::ptr_向量
这还允许您在对象具有较长寿命时从ptr_向量中移除阵列

关于try{}catch{}的注记
  • 参照
    • 如果通过特定类型捕获,则会接受切片问题,因为派生类型是复制构造到catch表达式中定义的变量中的
  • 更喜欢按常量ref捕捉
  • 再次投掷时使用投掷;(没有表达)
    • 这将重新抛出原始异常,而不是将新异常复制到异常处理机制在堆栈展开期间隐藏异常的位置

如果指针位于std容器内,则自动ptr没有任何用处,情况似乎就是这样here@Neil,不清楚OP是否需要将它们放入std容器中,如果他不使用它来跟踪需要删除的内容。这就是说,auto_ptr的使用要复杂得多…@Neil:我刚才说的是,可以使用类似于auto_ptr的阵列功能(如果不可用,也可以实现)。所以容器知道如何转移所包含元素的所有权。@ricebowl但是PHP和JS确实有垃圾收集@Phil H RAII(资源获取是初始化)不是一个图书馆,它是;这是一种技术。如果你不理解,你正在读错误的C++教科书。answer@Phil:使用std::vectors,而不是动态分配数组,因为没有人回答你的标题问题:是的。我看到的唯一问题是myArr应该被排除在这个背景之外。你需要复制向量。