在使用OpenGL动态显示的时候,在调试程序的时候窗口闪了一下便直接报错。
illegal glutInit() reinitialization attempt
后来找了下资料,找到个热心网友的回答,Helping me solve a great problem.
GLUT has not been designed in thread safety in mind (or even multiple threads support at all). So I am afraid, that with GLUT you won't be able to achieve what you want. However, GLFW seems to be much better in this matter:
Thread safety
Most GLFW functions may only be called from the main thread, but some may be called from any thread. However, no GLFW function may be called from any other thread until GLFW has been successfully initialized on the main thread, including functions that may called before initialization.
(大多数GLFW函数只能从主线程调用,但有些可以从任何线程调用。但是,在主线程上成功初始化GLFW之前,任何其他线程都不能调用GLFW函数,包括初始化前可能调用的函数。)
The reference documentation for every GLFW function states whether it is limited to the main thread.
The following categories of functions are and will remain limited to the main thread due to the limitations of one or several platforms:
- Initialization and termination
- Event processing
- Creation and destruction of window, context and cursor objects
This part seems quite important in your case:
Rendering may be done on any thread. The following context related functions may be called from any thread:
(呈现可以在任何线程上进行。可以从任何线程调用以下与上下文相关的函数:)
- glfwMakeContextCurrent
- glfwGetCurrentContext
- glfwSwapBuffers
- glfwSwapInterval
- glfwExtensionSupported
- glfwGetProcAddress
[...]
GLFW uses no synchronization objects internally except for thread-local storage to keep track of the current context for each thread. Synchronization is left to the application.
glutInit()函数,调用一次即可,
glutInit(&__argc, __argv),有内存泄漏,追溯代码,内存分配在glutInit函数内的如下位置:
void FGAPIENTRY glutInit( int* pargc, char** argv )
{
if( fgState.Initialised )
fgError( "illegal glutInit() reinitialization attempt" );
if (pargc && *pargc && argv && *argv && **argv)
{
fgState.ProgramName = strdup (*argv);
if( !fgState.ProgramName )
fgError ("Could not allocate space for the program's name.");
}
fgCreateStructure( );
}
函数strdup()会用malloc()分配内存,必须用free()释放,因此,追查fgState.ProgramName 释放的地方,发现回收资源的地方在如下函数:
void fgDeinitialize( void )
{
if( fgState.ProgramName )
{
free( fgState.ProgramName );
fgState.ProgramName = NULL;
}
}
那么fgDeinitialize是在什么地方被调用的呢?发现在这里:
/*
* Undoes all the "glutInit" stuff
*/
void FGAPIENTRY glutExit ( void )
{
fgDeinitialize ();
}
函数上的注释,就说明了一切,在程序退出前,调用glutExit(),内存泄漏从而被修补!
(PS:博主尝试过多次调用glutInit()函数,再进行gultExit()进行释放,虽然程序不报错了,但是窗口一直在闪烁,也就是一直创建,再删除,是无法实现博主的OpenGL动态显示的目的,所以gultinit()初始化函数,仅需调用一次即可,gultExit()其实不必调用)