【问题标题】:Why passing an object pointer to a method, where it is deleted, is different from deleting the object directly?为什么将对象指针传递给被删除的方法与直接删除对象不同?
【发布时间】:2011-07-18 18:28:17
【问题描述】:

导致一个block泄露的代码如下:

in = new RandomAccessFile(fileName, "r"); 在->关闭(); 内存::delObject(in);

其中RandomAccessFile 是带有string 字段的类,delObject() 是静态方法,如下所示:

void Mem::delObject(Object* object) { 删除对象; }

泄露的块是string的块。

如果我用直接的delete 替换方法delObject

in = new RandomAccessFile(fileName, "r"); 在->关闭(); 删除(在);

泄漏消失了。如果方法没有被替换,而是被移除:

in = new RandomAccessFile(fileName, "r"); 在->关闭(); // Mem::delObject(in); // 删除(输入);

有两个泄露的块。我猜是字段和包含它的对象。

那么:为什么这两种删除对象的方式不同?

【问题讨论】:

    标签: c++ memory-leaks


    【解决方案1】:

    我只能猜测,但您似乎在 Object 类中忘记了 virtual destructor。因此不会调用 RandomAccessFile 析构函数导致其属性泄漏。

    【讨论】:

    • +1;这是有道理的,因为函数签名中接受的指针是Object,而不是RandomAccessFile
    • @dark 那么为什么直接delete 有效?此外,Object 类及其子类RandomAccessFile 不包含任何动态分配的字段。
    • 因为您在 RandomAccessFile 对象上调用直接删除,所以编译器知道要调用什么析构函数。当您将它作为 Object * 传递给 delObject 函数时,编译器会丢失此信息。这些类实际上确实包含动态分配的字段 - std::string (通常)对其内容使用动态分配。
    • 更准确地说 - 您使用指针而不是对象调用 delete。所以当你delete in;in 的类型为RandomAccessFile* 时,就会调用 RandomAccessFile 析构函数。当您 delete object; 时,object 的类型为 Object*,因此如果 Object 的析构函数不是虚拟的,则行为未定义。似乎实际发生的是对象的Object 部分被破坏和删除,但对象的RandomAccessFile 部分永远不会被破坏,因此string 永远不会被破坏,因此动态分配的内存被保留string 永远不会被释放。
    • 谢谢!虚拟析构函数有所帮助。
    猜你喜欢
    • 2018-10-02
    • 1970-01-01
    • 2019-02-02
    • 1970-01-01
    • 2016-12-10
    • 1970-01-01
    • 2016-08-04
    • 2012-09-10
    • 2011-05-02
    相关资源
    最近更新 更多