【问题标题】:Consecutive use of std::list causes crash连续使用 std::list 会导致崩溃
【发布时间】:2017-07-06 17:24:48
【问题描述】:

我的代码是用来进行内存管理的,但是在我从“活动”列表中删除一个对象并将其放置到“死”列表中的某个点上,它总是崩溃:

class MemoryObject {
private:
    static std::list <MemoryObject *> alive, dead;
    long references;
public:
    MemoryObject() {
        alive.push_back(this);
        references = 0;
    }

    static void deepClean() {
        clean();
        std::list<MemoryObject *>::iterator iterator;
        for(iterator = alive.begin(); iterator != alive.end(); iterator ++) {
            MemoryObject *object = *iterator;
            Log::instance().write(DEBUG_LOG, "\nObject still active at the end of the program, check for memory leaks."
                    "\nSize: %d",
                    alive.size());
            delete object;
        }
        alive.clear();
    }

    void reference() {
        references ++;
    }

    void release() {
        references --;
        if(references <= 0) {
            dead.push_back(this);
            alive.remove(this);
        }
    }

    static void clean() {
        std::list<MemoryObject *>::iterator iterator;
        for(iterator = dead.begin(); iterator != dead.end(); iterator ++)
            delete(&iterator);
        dead.clear();
    }

    ~MemoryObject() {
        clean();
    }
};

std::list <MemoryObject *> MemoryObject::alive, MemoryObject::dead;

Eclipse 调试显示它在 release() 下失败,总是在第二个与列表相关的位置 - 我尝试将它们 (alive.remove(this) and dead.push_back(this)) 以不同的顺序放置,这没有任何改变。然而有趣的是,如果我在它们之间放置一些东西,比如 printf() 语句,它不会崩溃......

这里是我调用它的地方:

#include <stdlib.h>
#include <stdio.h>

#include "log/log.hpp"
#include "memory/object.hpp"

int main(int argc, char *argv[]) {
    MemoryObject foo;
    foo.release();
    MemoryObject::deepClean();
    return 0;
}

【问题讨论】:

  • 在你的clean 函数中你有delete(&amp;iterator)。这几乎不正确。
  • 请说明你是如何调用函数的。
  • 它并不清楚你想在这里实现什么。 foo的内存已经自动管理了,你不需要做任何额外的操作

标签: c++ eclipse stdlist


【解决方案1】:

在您的 clean 函数中,您有:

    delete(&iterator);

这将编译,但会尝试删除迭代器本身 - 它在堆栈上(将会崩溃)。

我怀疑你想要:

    delete(*iterator);

【讨论】:

    【解决方案2】:

    你不能删除一个没有用 new 分配的对象。 MemoryObject foo;未分配新的。

    【讨论】:

      【解决方案3】:

      delete只分配通过new

      MemoryObject foo;
      foo.release();
      

      里面很干净

      for(iterator = dead.begin(); iterator != dead.end(); iterator ++)
              delete(*iterator);  //I am assuming you have * instead of &(which is incorrect as mentioned in another answer).
      

      所以你在调用delete() 不是通过new分配的东西试试这个。

      MemoryObject *foo=new MemoryObject();
      foo->release();
      

      编辑:由于以下原因,这仍然不起作用。

      clean() 内,您正在删除dead 的元素,即当前对象的this。总之,您正在做这样的事情

      class A
      {
          void delete_this()
          {
              delete(this);
              //At this point "this" is a dangling pointer and you should not use it.
          } 
      };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-03-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-18
        相关资源
        最近更新 更多