在c ++中删除void *指针

时间:2013-04-08 16:29:11

标签: c++ void-pointers

我正在阅读c ++中的思考,第13章:动态对象创建。 在本章中,Eckel谈论删除void *可能是一个错误。 以下段落让我感到困惑。

  

另一个内存泄漏问题与确保删除有关   实际上调用了容器中保存的每个对象指针。该   容器不能“拥有”指针,因为它将它保存为void *和   因此无法进行适当的清理。用户必须负责   用于清理物体。如果你这会产生严重的问题   添加指向堆栈上创建的对象和创建的对象的指针   堆到同一个容器,因为delete-expression是不安全的   对于尚未在堆上分配的指针。

任何人都可以解释为什么“将指向堆栈上创建的对象的指针和堆上创建的对象添加到同一容器”会产生严重问题的详细信息?

为了更清楚地解决问题,我添加了相关的代码段。

class Stack {
  struct Link {
    void* data;
    Link* next;
    void initialize(void* dat, Link* nxt);
  }* head;
public:
  void initialize();
  void push(void* dat);
  void* peek();
  void* pop();
  void cleanup();
};

2 个答案:

答案 0 :(得分:2)

作为一般规则,堆栈上的对象不需要被删除,堆上的对象需要。如果将它们放在同一个容器中,如何跟踪要删除的容器?你最好有两个容器,一个用于堆栈上的对象(不需要删除的对象),另一个用于堆上的对象(需要删除的对象)。

答案 1 :(得分:0)

这一段确实有点模糊。在我看来,它混合了两个不同的问题,导致混乱。

  1. 为了正确删除对象,编译器必须知道其类型。对于void*,类型未知(这正是使用void* - 隐藏实际类型的重点)。因此,如果不转换为正确的实际类型,则无法对此类对象执行删除。
  2. 通常void*的使用意味着指向对象的所有权属于某个外部实体按设计,而不属于包含指针的实体。在实体内部,指针是不透明的,并且用作外部对象的处理程序,就实体而言,外部对象是一个黑盒子。 Stack类必须非常清楚责任划分,并且不得试图销毁void*对象,因为它不知道它的生命周期(例如,导致尝试释放堆栈变量),也没有关于破坏应该进行的操作(导致功能不正确)。