【发布时间】:2013-02-13 14:44:19
【问题描述】:
我目前正在检查我的一些代码是否存在内存泄漏,这种可能性让我很震惊。基本上我正在做的伪代码如下,
void thread_func()
{
char *fileName = malloc(someSize);
/* Do something with fileName and other things */
/* Enter a critical section */
modify some global variables
/*Exit critical section */
free(fileName);
return;
}
此函数位于 DLL 中。临界区和其他东西由同样驻留在同一个 DLL 中的函数初始化。
现在,我的主进程(这是一个 GUI)有一个取消按钮。当用户单击该按钮时,我调用 DLL 的清理函数,该函数恰好破坏了我的关键部分。
我发现如果用户在thread_func()执行过程中点击取消,thread_func()会继续执行。当它到达临界区代码时,临界区是无效的,所以我就退出了。这就是我在线程内检查取消事件的方式(因为在执行thread_func() 期间,我的应用程序中没有其他东西可以调用DLL 的清理)。
当我发现临界区无效时,我无法在thread_func() 中释放fileName。我的猜测是因为thread_func() 在主进程退出后失去了对fileName 的访问权限。我的猜测对吗?我的主要问题是,如果在这种情况下我不释放 fileName,我是否会面临内存泄漏的风险?
我已经搜索了很多相关信息,但到目前为止还没有找到任何东西。如果有人能指出正确的方向/回答我的问题,我会非常高兴。
谢谢!
编辑:
我决定根据kol的建议做一些初步测试(见下面的答案)。我注意到一些我无法理解的非常奇怪的东西。现在我的代码如下:
void thread_func()
{
char *fileName = malloc(someSize);
/* Do something with fileName and other things */
if(threadTerminated)
{
/* Cleanup */
return;
}
/* Enter a critical section */
modify some global variables
/*Exit critical section */
free(fileName);
return;
}
在我的 GUI 中,我的 OnCancel 事件处理程序类似于:
void OnCancel()
{
threadTerminated = TRUE;
WaitForMultipleObjects(noOfRunningThreads, threadHandles, TRUE, INFINITE);
/* Other cleanup code */
}
我注意到WaitForMultipleObjects() 无限期挂起,我的 GUI 变得无响应。 WaitForMultipleObjects()不应该快点回来吗?此外,如果 threadTerminated 是 TRUE,则不会在 thread_func() 中进行任何清理。
这是 IMO 最奇怪的部分。当我删除WaitForMultipleObjects() 时,我的代码运行良好!所有的清理工作都会发生,包括thread_func() 内部的清理工作。有人可以帮我理解一下吗?
请注意,我目前只检查threadTerminated。稍后我将在其他重要点检查它。我这样做只是为了看看我是否明白发生了什么。
再次感谢!您的回答非常有帮助。
【问题讨论】:
-
有不同类型的内存泄漏,在泄漏没有增长的情况下,它通常比实际问题更不方便,因为程序无论如何都会终止并且泄漏不会随着时间。
-
@claptrap,好点子!但我想删除我发现的任何内存泄漏情况。
-
如果 DLL 的清理函数只在进程退出时被调用,根本就不要费心破坏临界区。楼房拆了,不用扫地了!如果您需要处理正在卸载 DLL 但进程将继续进行的情况,那么您需要根据现有答案将清理与线程同步。请记住,即使没有关键部分,您也无法在线程仍在从中运行代码时安全地卸载 DLL。
标签: c windows memory-leaks