我正在阅读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();
};
答案 0 :(得分:2)
作为一般规则,堆栈上的对象不需要被删除,堆上的对象需要。如果将它们放在同一个容器中,如何跟踪要删除的容器?你最好有两个容器,一个用于堆栈上的对象(不需要删除的对象),另一个用于堆上的对象(需要删除的对象)。
答案 1 :(得分:0)
这一段确实有点模糊。在我看来,它混合了两个不同的问题,导致混乱。
void*
,类型未知(这正是使用void*
- 隐藏实际类型的重点)。因此,如果不转换为正确的实际类型,则无法对此类对象执行删除。void*
的使用意味着指向对象的所有权属于某个外部实体按设计,而不属于包含指针的实体。在实体内部,指针是不透明的,并且用作外部对象的处理程序,就实体而言,外部对象是一个黑盒子。 Stack
类必须非常清楚责任划分,并且不得试图销毁void*
对象,因为它不知道它的生命周期(例如,导致尝试释放堆栈变量),也没有关于破坏应该进行的操作(导致功能不正确)。