私が遭遇した問題は、単純化された FreeGLUT C++ アプリケーション内でのスレッド化のおそらく誤用によって発生します。
をエレガントに終了するglutMainLoop()ことはできないので、私はいくつかの作業を行うことに依存していますが、これはプログラムの機能glutLeaveMainLoop()に制御を戻すものではありません。GL 呼び出しの前に、ヒープ上に作成されたオブジェクト インスタンスへの関数にmain設定されるグローバル ポインターがあります。コールバックmainを使用しないと、このインスタンスでオペレーターを呼び出す人はいませんが、呼び出しの後にそのような操作を配置しました(無益であるため、コメントしました)。atexitdeleteglutMainLoop
これが私がやっていることの疑似コードです(フィルタリングするには長すぎるため、実際のコードは投稿しません):
CWorld* g_world;
AtExit()
{
delete g_world;
}
void main()
{
atexit(AtExit);
// create an instance of an object that creates a thread in its constructor
// via the new operator and joins this thread in its destructor
// calling the delete operator on that pointer to the thread instance
CWidget thisObjectCreatesATinyThread;
g_world = new CWorld();
...
glutMainLoop();
// delete g_world;
}
メイン関数には、コンストラクターで作成されたスレッドを介して何らかの作業を行うウィジェット インスタンスも含まれていることに注意してください。このスレッドはそのデストラクタに結合され、メモリは を介して割り当て解除されますdelete。
間違った動作: コールバックを設定しないと、オブジェクトatexitのデストラクタが呼び出されないため、リソース リークが発生します。CWorldこのコールバックを設定すると、関数が 1 回しか呼び出されないdeleteにもかかわらず、何らかの理由でオペレーターが 2 回呼び出されます。AtExit
この奇妙な動作の原因を探す場所はどこですか?
CWidget のインスタンス化を無効にしても、依然として独特の動作が得られます。