c - 线程分配内存,主进程死亡,会发生什么?

标签 c windows memory-leaks

我目前正在检查我的一些代码是否存在内存泄漏,这种可能性让我震惊。基本上我正在做的伪代码如下,

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() 不应该快速返回吗?此外,如果 threadTerminatedTRUE,则 thread_func() 中不会发生任何清理。

这是 IMO 最奇怪的部分。当我删除 WaitForMultipleObjects() 时,我的代码工作正常!所有清理都会发生,包括 thread_func() 中的清理。有人可以帮助我理解这一点吗?

请注意,我现在只在一个时间点检查 threadTerminated。稍后我会在其他重要的地方检查它。我这样做只是为了看看我是否了解正在发生的事情。

再次感谢!您的回答非常有帮助。

最佳答案

当进程终止时,操作系统将释放所有分配给它的内存,因此不对分配的 fileName 调用 free 不会造成任何问题。

无论如何,我会按以下方式更改代码:

  1. 定义一个指示线程是否应该终止的标志:bool terminated;
  2. 当进程即将终止时,设置terminatedtruewait for the thread to terminate .
  3. 在线程函数中,在重要的地方(例如,在每个循环的条件检查中)检查终止。如果 terminatedtrue,则停止线程所做的一切(例如,停止循环),释放资源(例如,线程分配的空闲内存),然后返回。
  4. 线程终止后(即线程函数返回后),进程可以释放所有剩余资源(例如进程分配的空闲内存、删除临界区等)并退出。

这样您就可以避免在线程终止之前删除临界区,并且您可以释放所有分配的资源。

关于c - 线程分配内存,主进程死亡,会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14856090/

相关文章:

memory-leaks - Java内存转储问题

c - 代码的时间复杂度或大O

c - K&R练习5-3 : passing pointers to functions

c++ - Win32 C/C++ 检查同一程序的两个实例是否使用相同的参数

c++ - window 打不开

c++ - 返回导致内存泄漏的 wchar_t 数组

opencv - 如何停止for循环(OpenCV)

c - 具有等待队列挂起系统的Linux驱动程序代码

c - 在 C 中定义包含不可打印字符的常量字符串

c# - 源文件 X 在 c# 中的 Windows 系统文件保护下?