C++ 避免两次删除内存

标签 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 被释放并且它运行到已经删除的内存中。

所以问题是内存空间被删除了两次,这样不好。一旦内存被删除,它就会被释放给其他程序使用,因此再次删除该内存空间将导致段错误。

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

我能想到的唯一方法是阻止 C1 对象取消分配它的队列,但取消分配其自身的其余部分,但我不知道该怎么做。如果有人可以帮我解决这个问题,我将不胜感激。

最佳答案

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

  • 人工重新盘点。强制每次将 Data 插入队列时,其引用计数都会增加,并在清理 Queue 时减少引用计数。当引用计数为零时,删除它(但要确保始终在堆上分配 Data!)
  • 指定一个对象“拥有”Data 元素。只有该对象可以销毁 Data(您甚至可以使用私有(private)析构函数和友元类强制执行此操作)。您可能需要不止一个。 (如果你引用这个代理,它就变成了一个穷人的 std::shared_ptr)。
  • 使您的Data 可复制,并且只需使用全新的对象即可完成所有操作。如果是少量不需要保持同步的数据(例如,包含两个整数的 Point2D 类),这会起作用。

关于C++ 避免两次删除内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15238543/

相关文章:

c++ - 在 C++ 中读取配置 xml 文件

java - xml 解析在 C/C++ 或 Java 中更快?

java - 将新对象添加到 ArrayList 会导致内存泄漏?

c++ - 如果在 VC 编译器中包含诸如 std::map 之类的容器,类的内存布局是什么

c++ - 删除数组而不调用析构函数

c# - 如何修复 'EntryPointNotFoundException'

C++ unordered_map 字符串与 int 键性能

java - 我遇到了泄漏窗口的问题,该窗口最初是在 onDoInBackground 显示文件更新隐藏后添加到此处的

linux - 程序是否需要退出才能让 Valgrind 工作?

c++ - Dev-C++ 和 Code::Blocks 中的析构函数困惑