我遇到的问题是由于在一个简单的 FreeGLUT C++ 应用程序中可能滥用线程而产生的。
由于退出glutMainLoop()
不能优雅地完成,我依靠glutLeaveMainLoop()
做一些工作,但这并没有真正将控制权交还给程序的main
功能。我有一个全局指针,它将在main
GL 调用之前在函数中设置到在堆上创建的对象实例。如果不使用atexit
回调,没有人会delete
在这个实例上调用操作员,尽管我在调用之后放置了这样的操作glutMainLoop
(现在因为它的无用而评论)。
这是我正在做的伪代码(我不会发布实际代码,因为它太长而无法过滤):
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;
}
请注意,在 main 函数中,我还包含了一个小部件实例,该实例通过在其构造函数中创建的线程完成一些工作。该线程在其析构函数中加入,然后通过delete
.
错误的行为:没有设置atexit
回调,我得到资源泄漏,因为CWorld
对象的析构函数不会被调用。如果我设置了这个回调,那么delete
操作符会因为某种原因被调用两次,即使该AtExit
函数只被调用一次。
在哪里寻找这种奇怪行为的根源?
即使我禁用 CWidget 实例化,我仍然会得到特殊的行为。