編輯:問題解決了。這是另一種情況,問題並不是它看起來真的那樣。線索是@ 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, [email protected], [email protected])
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);
正如你可以看到我打印出來的是什麼地址的一部分進入以及試圖從地圖中刪除的內容,並且它們與我預期的一致,所以我並不試圖抹去不存在的值或任何東西。
哦,還有最後一張紙條。這是一個奇怪的怪癖。如果我只打開一個窗口(即只添加一個元素到地圖),我可以把它擦掉。只有在向地圖添加兩個或更多元素之後,試圖擦除其中一個元素纔會導致分段錯誤。
我試圖把一個斷點HeapFree但它說這個函數沒有定義,可能這個名字被破壞了,我會看看我能否找到它 – cheshirekow 2009-08-19 03:13:05
OMG,謝謝,這正是我需要的線索,我無法找到一種方法來獲得HeapFree的蹤跡,但我認爲有一堆正在被釋放(並且它不應該),並且提醒我這個問題。所以這個類是引用計數的,並且 - > removeListener導致源對象放棄一個引用......但是它在課堂上第一次被添加時沒有正確地抓住參考 – cheshirekow 2009-08-19 03:35:36