添加元素到列表崩溃程序...有时

时间:2017-11-08 16:27:31

标签: c++ list pointers crash

我正在开发一个GUI项目,由于某种原因,以下调用add_gfx_object()会使我的程序崩溃。

MainMenuState::MainMenuState(Demo& demo)
    : m_start_button{new Button(Sol::Rectangle{Sol::Vector{10, 10}, 100, 30}, 
      [] {std::cout << "clicked";})}
{
    demo.add_gfx_object(m_start_button); // <-- crashes program
}

这里列出了Demo类中的相关代码。

class Demo : public Sol::Application
{
public:
    StateMachine<Demo> fsm;

    Demo();
    ~Demo();

    //...

    void add_gfx_object(const GraphicalEntity* const obj) {m_draw_list.push_back(obj);}

private:
    std::list<const GraphicalEntity*> m_draw_list;

    void draw_objects();
};

奇怪的是,对add_gfx_object()的调用不会导致程序崩溃。

Demo::Demo()
    : Application("Demo", 800, 600, false), fsm(*this, new MainMenuState(*this))
{
    add_gfx_object(new Button(Sol::Rectangle(), []{})); // <-- does not crash program
}

在这些示例中用nullptr替换Button指针会产生相同的结果。尽管我想提供有关该问题的其他信息,但我无法做到。谁能解释为什么我的程序不断崩溃?

1 个答案:

答案 0 :(得分:0)

这是您创建对象的顺序。

Application的构造函数列表和成员Demo的构造函数中调用Demo的基类(fsm)的构造函数。在Demo的构造过程中,首先构造基类,然后只有Demo的其他成员按照它们被声明的顺序构建 - 首先fsm并且只有在列表m_draw_list

但是对于fsm的构造函数,您尝试将调用的指针结果传递给传递给最后MainMenuState的{​​{1}}构造函数,并且是部分构造的*this没有列表的对象。因此,在调用Demo时,您的程序崩溃的意图是使用未初始化的列表。

您必须考虑如何组织代码并防止对象创建的循环依赖。您可能需要将一些参数传递给已经完全创建的对象,例如在构造函数的主体内部,其中所有成员都已构造,包括列表,如“工作”示例中所示。在这种情况下,您也可以在公开MainMenuState(Demo& demo)之前声明私人列表m_draw_list