c++ - 无法找到我的段错误的来源

标签 c++ segmentation-fault

编辑:问题已解决。这是(又一)情况,问题实际上并不像它看起来的那样。线索是使用 @0xfeeefefe 作为指向对象的指针。这是一个Windows API函数在释放内存时返回的地址...表示正在操作的对象已被删除。

我在尝试从 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

一些背景: 映射是指针到指针的映射。具体来说,key 是一个指向 gui 系统中窗口的指针,value 是一个指向对象的指针,该对象可以将要打印的信息发送到该窗口。还有一个从可调试对象到窗口的逆向映射。原因是如果窗口关闭,需要通知可调试对象,这样它就不会浪费时间尝试向它发送数据。反向映射是这样的,当管理器(该代码所在的类)从可调试对象接收到数据包时,它知道在哪个窗口中打印信息。

所以问题是为什么要比较两个指针值 return( 0x025e1ef8 < 0x025e1ef8 )造成故障?

我只尝试在我的代码中的某一点删除一些东西,而且它不在循环中,所以没有任何迭代器可以破坏。我也只在另一个地方将东西插入该 map ,并且在插入和删除东西时打印出痕迹,我看不出有什么问题。

我知道这些信息不足以真正提供帮助,但代码确实很大,我不确定我能做些什么来找出问题所在。如果有建议,我很乐意提供更多信息。我将粘贴部分代码,以便快速了解发生了什么。希望这里有一些东西可以表明我的问题是什么。

这是有问题的部分

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;
}

这是将元素添加到 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 );

如您所见,我正在打印正在进入的地址和试图从 map 中删除的地址,它们与我预期的一致,因此我不会尝试删除已失效的值或任何内容。

哦,还有最后一点。这是一个奇怪的怪癖。如果我只打开一个窗口(即只向 map 添加一个元素),我可以很好地删除它。只有在向 map 添加两个或更多元素后,试图删除其中一个元素才会导致段错误。

最佳答案

在实际比较之前,似乎发生了段错误,试图取消引用 0xfeeefefe

FEEEFEEE Used by Microsoft's HeapFree() to mark freed heap memory (1)

__x 和__y 的类型是什么?您能否验证写入 __x__y 的初始值,然后监视内存位置是否有任何更改?

此外,如果您可以在 HeapFree 函数上放置一个断点,您也许能够捕获错误的内存引用。

关于c++ - 无法找到我的段错误的来源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1297519/

相关文章:

c++ - 某些 lua/c++ 代码中的 SIGSEGV 错误

c - strcpy() 出现段错误(核心转储)错误(可疑)

c++ - C++类中对象计数的静态变量?

c++ - 我的 While 循环不会在条件处停止

C++出队问题......出队重复返回相同的元素

c++ - 断言、-NDEBUG 和段错误

ios - UIApplicationMain 方法在 iOS 10 中崩溃

c - SSL_CTX_new 中的段错误

c - 为什么动态分配 char** 和 char* 类型会使用 malloc 段错误?

c++ - GCC arm-none-eabi (Codesourcery) 和 C++ 异常