删除c+中的void*指针+; 我在C++中阅读思维,第13章:动态对象创建。 在本章中,Eckel谈到删除void*可能是一个bug。 下面这一段使我感到困惑

删除c+中的void*指针+; 我在C++中阅读思维,第13章:动态对象创建。 在本章中,Eckel谈到删除void*可能是一个bug。 下面这一段使我感到困惑,c++,void-pointers,C++,Void Pointers,另一个内存泄漏问题与确保删除被禁用有关 实际为容器中的每个对象指针调用。这个 容器无法“拥有”指针,因为它将指针作为一个空*和 因此无法执行正确的清理。用户必须对此负责 用于清理对象。这会产生一个严重的问题,如果你 添加指向在堆栈上创建的对象和在堆栈上创建的对象的指针 由于删除表达式不安全,因此将堆复制到同一容器 对于尚未在堆上分配的指针 有人能更详细地解释为什么“将指向在堆栈上创建的对象的指针和在堆上创建的对象添加到同一容器”会产生严重的问题吗 为了使问题更清楚,我添加了相关的代码片段 cla

另一个内存泄漏问题与确保删除被禁用有关 实际为容器中的每个对象指针调用。这个 容器无法“拥有”指针,因为它将指针作为一个空*和 因此无法执行正确的清理。用户必须对此负责 用于清理对象。这会产生一个严重的问题,如果你 添加指向在堆栈上创建的对象和在堆栈上创建的对象的指针 由于删除表达式不安全,因此将堆复制到同一容器 对于尚未在堆上分配的指针

有人能更详细地解释为什么“将指向在堆栈上创建的对象的指针和在堆上创建的对象添加到同一容器”会产生严重的问题吗

为了使问题更清楚,我添加了相关的代码片段

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();
};

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

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

  • 为了正确删除对象,编译器必须知道其类型。对于
    void*
    类型未知(这正是使用
    void*
    -隐藏实际类型的目的)。因此,如果不强制转换为正确的实际类型,则无法对此类对象执行删除
  • 通常使用
    void*
    意味着指向对象的所有权属于某个外部实体,而不是包含指针的实体。在实体内部,指针是不透明的,充当指向外部对象的处理程序,就实体而言,外部对象是一个黑盒。
    Stack
    类必须清楚地知道责任划分,并且不能尝试销毁
    void*
    对象,因为它既不知道对象的生存期(例如,导致尝试释放Stack变量),也不知道销毁时应执行的操作(导致功能不正确)

  • 我相信你误读了它的意思。它声明你不能删除一个非平凡对象的
    void*
    ,并且单独声明你不能删除可能指向堆栈的指针。可能是重复的,或者更好的是,让容器为你处理分配,这样你就不需要手动调用delete-RAII。