編集:問題は解決しました。これは (また別の) 状況で、実際には問題があるように見える場所ではありませんでした。手がかりは、@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; }
しかし、奇妙な部分は、これら 2 つの入力値の次の検査です。
(gdb) x 0x22f778
0x22f778: 0x025e1ef8
(gdb) x 0xfeeefefe
0xfeeefefe: 0x025e1ef8
背景: マップは、ポインターからポインターへのマッピングです。具体的には、キーは gui システムのウィンドウへのポインターであり、値はそのウィンドウに出力される情報を送信できるオブジェクトへのポインターです。デバッグ可能オブジェクトからウィンドウへの逆マップもあります。その理由は、ウィンドウが閉じている場合、デバッグ可能なオブジェクトに通知する必要があるためです。これにより、データを送信しようとして時間を無駄にすることができなくなります。逆マッピングは、マネージャー (このコードが含まれるクラス) がデバッグ可能なオブジェクトからパケットを受信したときに、どのウィンドウに情報を出力するかを認識できるようにするためのものです。
問題は、なぜ 2 つのポインター値を比較すると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 );
ご覧のとおり、何が起こっているのか、何がマップから消去されようとしているのかのアドレスを出力しています。それらは期待どおりに対応しているため、機能していない値などを消去しようとしているわけではありません。
あ、あと最後に一言。ここに奇妙な癖があります。ウィンドウを 1 つだけ開いた場合 (マップに要素を 1 つだけ追加した場合) は、問題なく消去できます。2 つ以上の要素をマップに追加した後でのみ、そのうちの 1 つを消去しようとするとセグメンテーション違反が発生します。