首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >FreeLibrary在VC14上泄漏,但在VC9上没有泄漏

FreeLibrary在VC14上泄漏,但在VC9上没有泄漏
EN

Stack Overflow用户
提问于 2017-05-29 14:21:59
回答 1查看 255关注 0票数 0

我使用的是第三方库,它显然存在内存泄漏,这是我们在从Visual 2008 (VC9.0)升级到Visual 2015 (VC14.0)时首次发现的。在Windows上,我使用LoadLibrary在运行时加载库,当使用它时我使用FreeLibrary卸载它。在使用VC9.0编译和链接时,库分配的所有内存都在FreeLibrary上释放,而使用VC14.0时,一些内存从未被释放。下面的测试程序的内存配置文件可以在这里看到:http://imgur.com/a/Hmn1S

为什么VC9.0和VC14.0的行为不同?如果不改变库的源,比如模仿VC9.0的行为,人们能做些什么来避免泄漏吗?

我在这里唯一能找到的就是:Memory leaks on DLL unload,它并没有真正帮助我,尽管有一个答案暗示了一些棘手的解决方案。

我已经做了一个最小的工作例子,以表明它并不是特定于库的。首先,我在C中创建了一个小库,其中包含一个函数,该函数分配一些内存,并且从不释放它:

漏水:

代码语言:javascript
复制
#ifndef LEAKLIB_H_
#define LEAKLIB_H_

__declspec( dllexport ) void leak_memory(int memory_size);

#endif

泄密c:

代码语言:javascript
复制
#include "leaklib.h"

#include <stdio.h>
#include <stdlib.h>

void leak_memory(int memory_size)
{
    double * buffer;
    buffer = (double *) malloc(memory_size);
    if (buffer != NULL)
    {
        printf("Allocated %d bytes of memory\n", memory_size);
    }
}

然后是一个加载库的程序,调用内存泄漏函数,然后再次卸载库,这样我们就可以随着时间的推移跟踪内存。

备忘录泄密c:

代码语言:javascript
复制
#include <windows.h>
#include <stdio.h>

int main(void)
{
    int i;
    HINSTANCE handle;
    int load_success;
    void (*leak_memory)(int);
    int dll_unloaded;

    Sleep(30000);

    for (i = 0; i < 100; ++i)
    {
        handle = LoadLibrary(TEXT("leaklib.dll"));

        leak_memory = GetProcAddress(handle, "leak_memory");

        printf("%d: leaking memory...\n", i);
        leak_memory(50*1024*1024);
        printf("ok\n\n");

        Sleep(3000);

        dll_unloaded = FreeLibrary(handle);
        if (!dll_unloaded)
        {
            printf("Could not free dll'");
            return 1;
        }

        Sleep(3000);
    }

    return 0;
}

然后,我使用以下内容构建库:

代码语言:javascript
复制
cl.exe /MTd /LD leaklib.c

和程序与

代码语言:javascript
复制
cl.exe memleak.c

使用VS9.0或VS14.0中的cl.exe。

EN

回答 1

Stack Overflow用户

发布于 2017-05-29 15:23:36

真正的问题是,VC9无意中释放了一个合理的程序可能期望仍然存在的内存--毕竟,free()没有被调用。当然,这是CRT无法取悦每个人的领域之一--您想要的是自动free行为。

实际上,FreeLibrary是一个非常简单的Win32函数。它从您的地址空间中删除一段代码。您可能会收到一些对DllMain的最后调用,但正如DllMain的文档所指出的:您不能在那里做太多事情。特别困难的是,除了DLL的代码和数据段之外,还需要找出需要释放哪些内存。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44244806

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档