[英]c++ Segmentation fault with list iterator
I have trouble accessing an iterator pointing at a list inside a map. 我在访问指向地图内列表的迭代器时遇到麻烦。 Despite the number of similar problems described on internet, I didn't find a correct explanation. 尽管互联网上描述了许多类似的问题,但我没有找到正确的解释。
I have a manager object which contains "Visible Object"s ; 我有一个包含“可见对象”的管理器对象; they are stored in a map when they're single, and in a list inside a map when they can be multiple with a same name. 单身时,它们将存储在地图中;当它们相同时,它们将被存储在地图中的列表中。 I have some functions that must browse the whole maps, and the program crashes when trying to access the list iterator. 我有一些必须浏览整个地图的函数,并且在尝试访问列表迭代器时程序崩溃。
I will try to give you only what's necessary, ask for more if needed. 我将尝试只给您必要的东西,如果需要的话,请您提供更多。
Manager.h : 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;
};
In Manager.cpp : 在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)
}
There should already be 2 single objects and many listed objects when crashing. 崩溃时应该已经有2个单个对象和许多列出的对象。
I didn't change the constructor because it doesn't look like something needs to be initialized (The only problem being when accessing the list). 我没有更改构造函数,因为它看起来好像不需要初始化(唯一的问题是访问列表时)。 VisibleObject::draw(...) is virtual. VisibleObject :: draw(...)是虚拟的。
EDIT : The manager is an attribute from the static class Game. 编辑:管理器是静态类Game的属性。 Here is the part where I can get the manager from any class and a function which add some objects : 这是我可以从任何类和添加一些对象的函数中获取管理器的部分:
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);
/* ... */
}
I add Visible Objects in the constructor of the object Grid. 我在对象Grid的构造函数中添加可见对象。 I think it doesn't need more explanation : 我认为不需要更多说明:
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);
}
The Manager's destructor is supposed to delete every objects (but it's not relevant for the problem, is it ?) Manager的析构函数应该删除每个对象(但这与问题无关,是吗?)
The problem is most likely due to dangling pointers. 问题很可能是由于指针悬空。 I don't see any code that updates the list in Manager
when a VisibleObject
gets deleted. 删除VisibleObject
时,看不到任何更新Manager
列表的代码。 Divide the line 分界线
(*listItr)->draw(p_window);
into 成
VisibleObject* object = *listIter;
object->draw(p_window);
Then, you can tell whether the problem is with the list iterator, I suspect it is not, or the problem is caused by a dangling pointer. 然后,您可以判断问题出在列表迭代器上,还是怀疑不是,或者问题是由指针悬空引起的。
When trying to create a list to add objects, this list was declared and deleted in a function (as suggested by R sahu) : here is the wrong code : 尝试创建要添加对象的列表时,此列表已在函数中声明和删除(如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);
When reaching the end of the "Manager::addObjectToList" function, this list was deleted, but still pointed by the manager. 到达“ Manager :: addObjectToList”函数的末尾时,此列表已删除,但仍由管理器指向。 I created it with a pointer instead : 我用指针创建它:
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);
EDIT : There was also a problem when I added Squares to an object list : I initialized Squares with a nullptr, the program could not access Square's functions. 编辑:当我将Squares添加到对象列表时,还有一个问题:我使用nullptr初始化了Squares,程序无法访问Square的函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.