C ++避免两次删除内存

时间:2013-03-06 03:39:36

标签: c++ memory-leaks destructor memory-management

我在使用C ++中的内置指针时遇到了问题。当我的程序终止时,我的类析构函数都被调用。我有一个数据类,一个队列类和另一个合并使用队列的数据类如下(请记住动态粗略编码):

class Data {
  int x;
}

class Queue {
  class Node {
    Data* x;
  }
  Node* head;
}

class C1 {
  Queue q;
}

class C1Queue{
  class Node {
    C1* c;
  }
  Node* head;
}

我还有一个不存在于对象中的另一个队列q2。我从一个文件加载两个队列,所以我说的是(假设cQueue是C1Queue):

Data *d = new Data(0);
q2->pushBack(d);
C1 c = new C1();
cQueue->pushBack(c->pushBack(d));

正如您所看到的,我有一个队列(q2),其中包含指向每个数据的指针,以及一个队列,其中包含指向q2所持有的相同数据的指针。 现在,当我的程序终止时,我希望释放所有数据。但是,当对象被释放时,首先释放q2,并且当要释放C1对象时,然后它们解除分配它们的队列,然后删除与刚刚删除的q2相同的数据。或者另一种情况是首先释放对象(我不确定发生了哪种排序),然后q2被解除分配并且它会运行到已经删除的内存中。

所以问题是内存空间被删除了两次,这并不好。删除内存后,将其释放给其他程序使用,因此再次删除该内存空间将导致seg错误。

也许我在这里遗漏了一些东西,但是如果没有特殊类型的指针(我不能使用特殊类型的指针),我无法弄清楚如何做到这一点。

我能想到的唯一方法是阻止C1对象解除分配它的队列但释放其余部分,但我不知道该怎么做。如果有人可以帮助我,那么我会非常感激。

1 个答案:

答案 0 :(得分:1)

由于您(显然)无法使用std::shared_ptr这样的细节,您可以尝试以下三种补救措施之一:

  • 手动重新计数。每次将Data推送到队列以使其refcount递增时强制执行,并在清除Queue时递减refcount。当引用计数达到零时,delete this(但请确保始终在堆上分配Data!)
  • 指定一个“拥有”Data元素的对象。只有该对象可以销毁Data(您甚至可以使用私有析构函数和友元类来强制执行此操作)。您可能需要不止一个。 (如果你重新计算这个代理,这就变成了一个穷人的std::shared_ptr)。
  • 使Data可复制,并使用全新的对象执行所有操作。如果它是少量不需要保持同步的数据(例如,一个包含两个整数的Point2D类),则可以正常工作。