防止指针的双重删除

时间:2014-08-31 18:17:48

标签: c++ algorithm pointers memory-management

我的程序中有一个vector<Points*> points;size: 6所有唯一的Points),其中我在迭代点以在屏幕上绘制内容。但是,根据我的新要求,我要将向量的长度增加到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)导致true i=6,7...13

3 个答案:

答案 0 :(得分:7)

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

2014年最佳智能指针奖获得者&#34;是std::unique_ptr std::shared_ptr,当你需要复制指针的那些时候,{{1}}会有荣誉提名。

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

答案 1 :(得分:4)

原因是通过删除,对同一内存的其他引用未设置为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. 只需复制。

答案 2 :(得分:0)

通用答案是,当您使用动态内存时,有一个清理计划。

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

“最佳”计划取决于手头的应用类型。例如,当您使用某些图形结构时,当该方法与其他类型的结构一起工作时,引用计数可能不起作用。

例如,如果您在

时尝试进行引用计数
A points to B.
B points to C and D
C and D points to E
E points to B

这给出了以下参考计数

B 2 C 1 D 1 E 2

销毁链接A-> B给出这些参考计数

B 1 C 1 D 1 E 2

没有引用结构,因此永远不会被删除。

为您的情况选择最佳方案。