EDIT: Problem solved. This was (yet another) situation where the problem wasn't really where it looked like it was. The clue was the use of @0xfeeefefe as a pointer to an object. This is an address that is returned by a windows API function when freeing memory... indicating that the object that was being operated on had been deleted.
I'm receiving a segmentation fault while trying to erase a value from a std::map, but I cannot for the life of me figure out why. From the debugger (gdb) I see:
Program received signal SIGSEGV, Segmentation fault.
0x0048785f in std::less<irr::gui::IGUIWindow*>::operator()(irr::gui::IGUIWindow* const&, irr::gui::IGUIWindow* const&) const (this=0x258ab04, __x=@0x22f778, __y=@0xfeeefefe)
at C:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/c++/3.4.5/bits/stl_function.h:227
227 { return __x < __y; }
But the weird part is the following examination of those two input values:
(gdb) x 0x22f778
0x22f778: 0x025e1ef8
(gdb) x 0xfeeefefe
0xfeeefefe: 0x025e1ef8
Some background: The map is a mapping of pointers to pointers. Specifically, the key is a pointer to a window in a gui system, and the value is a pointer to an object that may send information to be printed to that window. There is also an inverse map from the debuggable object to the window. The reason is that if the window is closed, the debuggable object needs to be informed so it can not waste time by trying to send data to it. The inverse mapping is so that when the manager (the class this code is inside of) receives a packet from a debuggable object, it knows which window to print the information in.
So the question is why would a comparison of two pointer values, return( 0x025e1ef8 < 0x025e1ef8 )
cause a fault?
I only try to erase things at one point in my code, and it's not in a loop so there aren't any iterators to corrupt. I also only insert things into that map at one other place and I have traces that print out when things are being inserted and erased and I can't see anything wrong with that.
I know this isn't enough information to really help, but the code is really large and I'm not sure what I can do to track down the problem. I would be happy to provide any more information if there are suggestions. I'll paste some of the parts of the code for a quick idea of what's going on. Hopefully there is something in here to indicate what my problem is.
Here's the part with the problem
case EGET_ELEMENT_CLOSED:
{
IGUIWindow* window =
static_cast<IGUIWindow*>(event.GUIEvent.Caller);
if( m_debugMap.find(window) != m_debugMap.end())
{
IGuiDebuggable* debug = m_debugMap[window];
debug->removeListener(this);
cout << "closing window: " << window << " attached"
" to debuggable: " << debug << endl;
m_debugMap.erase(window); /// segfault here
m_conMap.erase(debug); /// if above line commented, segfault here
}
m_eventMap.erase(window); /// if above block commented, segfault here
window->remove();
return true;
}
And here's the part where an element is added to the map
IGUIElement* winElmnt =
m_env->getRootGUIElement()->getElementFromId(0,false);
IGUIElement* editElmnt = winElmnt->getElementFromId(1);
IGUIWindow* window = static_cast<IGUIWindow*>(winElmnt);
cout << "CModelTesterGui: adding " << window << "(" << winElmnt
<< ") to the debug map with edit box " << editElmnt << endl;
m_conMap[debug] = static_cast<IGUIEditBox*>(editElmnt);
m_debugMap[window] = debug;
window->setID(-1);
debug->addListener( this );
As you can see I'm printing out the addresses of what is going into and what is attempting to be erased from the map, and they correspond as I would expect so I'm not trying to erase defunct values or anything.
Oh, and a final note. Here's a weird quirk. If I only open one window (i.e. only add one element to the map) I can erase it fine. It's only after adding two or more elements to the map that trying to erase one of them causes a segmentation fault.