繁体   English   中英

如何在C ++ DLL中释放已分配的内存

[英]How to free allocated memory in C++ DLL

我有以下代码来加密C ++ DLL中的字符串

EXPORT WCHAR* EncryptString(WCHAR* stringToEncrypt) {
    aes_context ctx;

    WCHAR* in = stringToEncrypt;
    WCHAR* out;
    WCHAR* key = L"TestKey";

    BYTE* buffEnc = (BYTE*)malloc(16);
    BYTE* keyBuffEnc = (BYTE*)malloc(32);

    memset(buffEnc, 0, 16);
    memset(keyBuffEnc, 0, 32);

    memcpy(buffEnc, in, wcslen(in) * 2);
    memcpy(keyBuffEnc, key, wcslen(key) * 2);
    aes_set_key(&ctx, keyBuffEnc, 256);

    aes_encrypt(&ctx, buffEnc, buffEnc);
    out = (WCHAR*)buffEnc;

    // free(buffEnc);   
    // free(keyBuffEnc);

    return out;
}

我的问题是我无法释放分配的内存,否则结果会被破坏。 我想知道如何在不丢失结果的情况下释放使用过的内存? 我要改变返回值的类型吗?

在此先感谢您的帮助。 迎接亨氏

这确实是一个有问题的情况 - 你返回一个指向已分配内存的指针,并且不清楚谁应该释放内存。 您有以下选择:

  1. 告诉调用者使用free()释放内存 - 这只有在他们使用难以保证的相同堆时才会起作用。 这是非常不可靠的,并不是真的推荐。
  2. 引入一个内存管理接口(例如你的库中实现的freeEncrypted()函数)并告诉调用者使用它 - 然后内存将返回到正确的堆。
  3. 使用像CoTaskMemAlloc()这样众所周知的东西进行分配,并告诉调用者使用匹配函数(如CoTaskMemFree()来释放内存。 这类似于第2点,只使用一个众所周知的通用内存管理器。
  4. 更改接口,使其接受指向已分配数据及其大小的指针,以便调用者分配和释放内存。

在Windows上,内存管理器(其中包括跟踪进程中分配的和可用内存)在C运行时库中工作。 这意味着如果你有两个模块(比如:你的实际可执行文件和一个DLL,或两个DLL),你想让一个模块分配一些内存而另一个模块应该拥有它(即负责释放它或传递它维护人员基本上有三种选择:

  1. 您让调用者分配一块内存并将指针传递给被调用者。 在您的示例中,这将归结为调用者分配一个(希望足够大)缓冲区,然后将指针传递给EncryptString函数。 这种方法的优点是调用者可以选择在堆栈上分配一块内存,然后将指针传递给它,类似于

     WCHAR buf[1024]; EncryptString( "Hello", buf ); // Won't compile, "Hello" is a const string 

    缺点是调用者必须首先找出合适的缓冲区大小。 您可以强加一个最大限制并记录该文件,或者您可以使用公开的专用函数来计算所需的大小,或者您可以说如果将NULL作为输出缓冲区传递,则该函数返回所需字符的数量。 后者通常由Windows API使用。

  2. 你让被调用者使用例如mallocnew来分配内存(正如你的函数所做的那样)但是然后要求调用者必须使用特殊函数再次释放内存,比如FreeEncryptedString(char *s) 这个想法是你的DLL也暴露了这个释放函数,它只是调用适当的释放函数(即freedeletedelete[]等),这样分配和释放都发生在同一个模块中。

  3. 您确保两个模块动态链接到同一个C运行时库,即在此过程中只有一个C运行时DLL副本,并且两个模块都使用它。 在这种情况下,您可以根据需要使用mallocfree (或newdelete等)。 这样做的好处在于它非常简单,缺点是它意味着你对模块的构建方式提出了要求(如果你在加载由其他人编写的插件的程序上工作,这可能是不可能的 - 这些插件可能选择静态链接C运行时)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM