防止指针的双重删除

Preventing double deletion of pointers

本文关键字:删除 指针      更新时间:2023-10-16

我的程序中有一个vector<Points*> points;(具有所有唯一Pointssize: 6),我在其中迭代点以在屏幕上绘制一些东西。然而,根据我的新要求,我想将向量的长度增加到size: 14

要添加的新项目必须来自以前的6 Points,所以我没有分配新的内存,而是考虑如下使用以前的指针:

while (currentSize < 14){
  int rndPoint = getRandomPoint(0, 5); //random index to choose from the vector
  points->push_back(points[randPoint]);
}

在类的析构函数中,当我必须释放内存时,我会执行以下操作:

for(int i=0;i<points.size(); ++i){
  if(points[i] != NULL){
    delete (points[i]);
  }
}

然而,当我试图退出程序时,我在循环中遇到了访问冲突错误(特别是当i达到索引6时)。当我已经使用delete删除了6个唯一点时,为什么条件if (points[i] != NULL)会导致i=6,7...13true

使用智能指针。如果程序的源包含delete,并且它不在智能指针的删除程序中,则程序已损坏。(为什么你会那样做而不是std::default_deleter?)。

"2014年最佳智能指针奖"的得主是std::unique_ptr,在那些你只需要复制指针的时候,std::shared_ptr值得一提。

零规则意味着您几乎不需要自己实现析构函数等,因为您应该始终使用通用资源管理类来自己管理它。

原因是通过删除,对同一内存的其他引用不会设置为nullptr(或0,在C++11之前)。考虑:

int *foo = new int;
// foo should be non-nullptr now
int *bar = foo;
// bar should be non-nullptr now
delete foo;
// both foo and bar are still non-nullptr.

有三种方法可以解决您的特定问题:

  1. 使用std::shared_ptr
  2. 唯一实例提供单独的std::vector

    std::vector<Point> unique_points;
    std::vector<Point*> used_points;
    // create all needed points *once* in unique_points
    // insert pointers to the points in unique_points into used_points
    
  3. 只需复制即可。

一般的答案是,当您使用动态内存时,有一个用于清理的PLAN。

一种方案是使用各种形式的标准库模板指针管理器(如上所述)。然而,还有其他方法可以做到这一点。

"最佳"计划取决于手头的应用程序类型。例如,当您使用某些图结构时,当该方法适用于其他类型的结构时,引用计数可能不起作用。

例如,当你有时,如果你试图进行参考计数

A points to B.
B points to C and D
C and D points to E
E points to B

这给出了以下参考计数

B 2C 1D 1E 2

破坏链接A->B会给出这些参考计数

B 1C 1D 1E 2

并没有引用该结构,所以它永远不会被删除。

为您的情况选择最佳计划。