我在尝试从std :: map中删除一个值时遇到了分段错误,但我不能为我的生活找出原因。从调试器(gdb)我看到:
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; }
但奇怪的部分是对这两个输入值的以下检查:
(gdb) x 0x22f778
0x22f778: 0x025e1ef8
(gdb) x 0xfeeefefe
0xfeeefefe: 0x025e1ef8
一些背景: 地图是指针指针的映射。具体地,键是指向gui系统中的窗口的指针,并且该值是指向可以将要打印的信息发送到该窗口的对象的指针。还有从可调试对象到窗口的反向映射。原因是如果窗口关闭,则需要通知可调试对象,这样就不会因为尝试向其发送数据而浪费时间。逆映射是这样的,当管理器(此代码所在的类)从可调试对象接收数据包时,它知道在哪个窗口中打印信息。
所以问题是为什么比较两个指针值return( 0x025e1ef8 < 0x025e1ef8 )
会导致错误?
我只是尝试在代码中的某一点擦除事物,并且它不在循环中,所以没有任何迭代器可以破坏。我也只在另一个地方将东西插入到地图中,并且当插入和删除内容时我会打印出来的痕迹,我看不出有什么问题。
我知道这不是真正有用的信息,但代码非常庞大,我不知道我能做些什么来追查问题。如果有建议,我很乐意提供更多信息。我将粘贴代码的一些部分,以便快速了解正在发生的事情。希望这里有一些东西可以表明我的问题是什么。
这是问题部分
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;
}
这是元素添加到地图的部分
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 );
正如你所看到的那样,我正在打印出地图中正在进行的地址以及试图从地图中删除的地址,并且它们符合我的预期,因此我不会尝试删除已失效的值或其他任何内容。
哦,最后一点。这是一个奇怪的怪癖。如果我只打开一个窗口(即只向地图添加一个元素),我可以将其擦除。只有在向地图添加两个或更多元素后,尝试擦除其中一个元素才会导致分段错误。
答案 0 :(得分:2)
哦,最后一点。这有点奇怪 怪癖。如果我只打开一个窗口(即 只添加一个元素到地图)我可以 擦掉它。它只是在添加之后 地图上有两个或多个元素 试图擦除其中一个导致a 分段错误。
奇怪的怪癖通常代表记忆问题。你试过运行valgrind吗?
您是否正在插入克隆?指针是否在地图插入和删除之间的某处被删除?
答案 1 :(得分:2)
在实际比较之前,尝试解除引用0xfeeefefe
似乎发生了段错误。
微软公司使用的FEEEFEEE HeapFree()标记释放的堆内存(1)
__
x和__y
有哪些类型?您是否可以验证写入__x
和__y
的初始值,然后监视内存位置是否有任何更改?
此外,如果您可以在HeapFree
函数上设置断点,则可能会捕获错误的内存引用。
答案 2 :(得分:1)
我在看你的追溯,我看到它在哪里
__x = @ 0x22f778,__ y = @ 0xfeeefefe
这似乎表明__x和__y是引用。
在这种情况下,尝试测试(__x&lt; __y)可能会取消引用它们,并且解除引用0xfeeefefe可能不是一件好事,除非你的机器安装了beaucoup内存。