c ++使用列表迭代器进行分段错误

时间:2015-08-06 17:11:01

标签: c++ list pointers iterator segmentation-fault

我无法访问指向地图内列表的迭代器。 尽管在互联网上描述了类似的问题,但我没有找到正确的解释。

我有一个包含“可见对象”的管理器对象;它们在单个时存储在地图中,在地图中的列表中存储时,它们可以是具有相同名称的多个。我有一些必须浏览整个地图的函数,并且在尝试访问列表迭代器时程序崩溃。

我会尽量只给你一些必要的东西,如果需要的话还要求更多。

Manager.h:

class VisibleObject;

class Manager
{
public:
    ~Manager ();

    bool addObject (std::string, VisibleObject*);
    bool addObjectToList (std::string, VisibleObject*);

    bool removeObject (std::string);
    bool removeObjectList (std::string);
    void clean ();

    VisibleObject* getObject (std::string);
    std::list<VisibleObject*>* getObjectList (std::string);

    void updateAll (float);
    void drawAll (sf::RenderWindow&);

private:
    std::map<std::string, VisibleObject*> m_objects;
    std::map<std::string, std::list<VisibleObject*>> m_objectLists;
};

在Manager.cpp中:

/// Add a single object
bool Manager::addObject (std::string p_name, VisibleObject* p_object)
{
    std::map<std::string, VisibleObject*>::iterator itr = m_objects.find(p_name);
    if (itr != m_objects.end())
        return false;
    m_objects.insert(std::pair<std::string, VisibleObject*> (p_name, p_object));
    return true;
}

/// Add an object to a list (create list if needed)
bool Manager::addObjectToList (std::string p_name, VisibleObject* p_object)
{
    std::map<std::string, std::list<VisibleObject*>>::iterator itr = m_objectLists.find(p_name);
    if (itr != m_objectLists.end())
    {
        itr->second.push_back(p_object);
        return true;
    } else
    {
        std::list<VisibleObject*> objectList;
        m_objectLists.insert(std::pair<std::string, std::list<VisibleObject*>> (p_name, objectList));
        m_objectLists[p_name].push_back(p_object);
        return false;
    }
}

/// This is where the problem occures
void Manager::drawAll (sf::RenderWindow& p_window)
{
    for (std::map<std::string, VisibleObject*>::iterator itr = m_objects.begin() ; itr != m_objects.end() ; itr++)
        (*itr).second->draw(p_window); // Seems to work fine
    for (std::map<std::string, std::list<VisibleObject*>>::iterator mapItr = m_objectLists.begin() ; mapItr != m_objectLists.end() ; mapItr++)
        for (std::list<VisibleObject*>::iterator listItr = (*mapItr).second.begin() ; listItr != (*mapItr).second.end() ; listItr++)
            (*listItr)->draw(p_window); // This is when I get a segmentation fault while debugging (signal SIGSEGV)
}

崩溃时应该已经有2个单个对象和许多列出的对象。

我没有更改构造函数,因为它看起来不像需要初始化的东西(访问列表时唯一的问题)。 VisibleObject :: draw(...)是虚拟的。

编辑:经理是静态类游戏的属性。以下是我可以从任何类中获取管理器的部分以及添加一些对象的函数:

Manager& Game::getManager ()
{
    return m_manager;
}

void Game::start ()
{
    Grid *grid = new Grid();
    m_manager.addObject("GRID", grid);
    Tetrimino *tetrimino = new Tetrimino();
    m_manager.addObject("TETRIMINO", tetrimino);
    /* ... */
}

我在对象Grid的构造函数中添加了Visible Objects。我认为不需要更多解释:

Grid::Grid ()
{
    VisibleObject::load("ressources/grid.png");
    Square *square = NULL;
    m_gridWidth = Game::getSettings().getInt("GRIDWIDTH");
    m_gridHeight = Game::getSettings().getInt("GRIDHEIGHT");
    m_squares.assign(m_gridWidth*m_gridHeight, square);
    Manager &manager = Game::getManager();
    for (int i=0 ; i<m_gridWidth*m_gridHeight ; i++)
        manager.addObjectToList("SQUARE", square);
}

管理器的析构函数应该删除每个对象(但它与问题无关,是吗?)

2 个答案:

答案 0 :(得分:0)

问题很可能是悬挂指针造成的。当Manager被删除时,我没有看到任何更新VisibleObject列表的代码。划分线

(*listItr)->draw(p_window);

VisibleObject* object = *listIter;
object->draw(p_window);

然后,您可以判断问题是否与列表迭代器有关,我怀疑它不是,或者问题是由悬空指针引起的。

答案 1 :(得分:0)

当尝试创建添加对象的列表时,此列表在函数中声明并删除(如R sahu所建议):这是错误的代码:

std::list<VisibleObject*> objectList;
m_objectLists.insert(std::pair<std::string, std::list<VisibleObject*>> (p_name, objectList));
m_objectLists[p_name].push_back(p_object);

到达&#34; Manager :: addObjectToList&#34;功能,此列表已删除,但仍由经理指出。我用指针创建了它:

std::list<VisibleObject*>* objectList = new std::list<VisibleObject*>;
m_objectLists.insert(std::pair<std::string, std::list<VisibleObject*>> (p_name, *objectList));
m_objectLists[p_name].push_back(p_object);
编辑:当我将Square添加到对象列表时也存在问题:我使用nullptr初始化Squares,程序无法访问Square的函数。