如何释放 DLL C++中分配的内存
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;
}
我的问题是我无法释放分配的内存,否则结果会损坏。我想知道如何在不丢失结果的情况下释放已用内存?我必须更改返回值的类型吗?
提前感谢您的帮助。问候海因茨
这确实是一个有问题的情况 - 你返回一个指向分配内存的指针,并且不清楚谁应该释放内存。您有以下选项:
- 告诉调用方使用
free()
释放内存 - 这只有在他们使用相同的堆时才有效,这很难保证。这是非常不可靠的,并不真正推荐。 - 引入内存管理接口(例如
freeEncrypted()
库中实现的函数(并告诉调用者使用它 - 然后内存将返回到正确的堆。 - 使用众所周知的
CoTaskMemAlloc()
进行分配,并告诉调用方使用匹配函数(如CoTaskMemFree()
(来释放内存。这类似于第 2 点,只是使用了一个众所周知的公共内存管理器。 - 更改接口,使其接受指向已分配数据的指针及其大小,以便调用方分配和释放内存。
在 Windows 上,内存管理器(除其他外,它跟踪进程中分配的和可用的内存(在 C 运行时库中工作。这意味着,如果你有两个模块(比如:你的实际可执行文件和一个DLL,或两个DLL(,并且你想允许一个模块分配一些内存,另一个应该拥有它(即负责释放它或传递维护者(,基本上有三个选项:
-
您让调用方分配一段内存,并将指向该内存的指针传递给被调用方。在您的示例中,这将归结为调用方分配一个(希望足够大的(缓冲区,然后将指向该缓冲区的指针传递给
EncryptString
函数。这种方法的优点是,调用方可以选择只在堆栈上分配一段内存,然后传递一个指向该内存的指针,类似于WCHAR buf[1024]; EncryptString( "Hello", buf ); // Won't compile, "Hello" is a const string
缺点是调用方必须首先确定适当的缓冲区大小。您可以只施加最大限制并记录它,或者您可以公开一个专用函数来计算所需的大小,或者您可以说如果
NULL
作为输出缓冲区传递,则该函数返回所需字符数。后者通常由Windows API使用。 -
你让被调用方分配内存(就像你的函数现在所做的那样(,例如
malloc
或new
但随后指示调用者必须使用特殊功能再次释放内存,例如FreeEncryptedString(char *s)
.这个想法是这个释放函数也由你的DLL公开,它只是调用适当的释放函数(即free
或delete
或delete[]
等(,以便在同一模块内进行分配和解除分配。 -
确保两个模块动态链接到同一个 C 运行时库,即进程中只有一个 C 运行时 DLL 副本,并且两个模块都使用它。在这种情况下,您可以根据需要使用
malloc
和free
(或new
和delete
等(。这样做的优点是它非常简单,缺点是这意味着你对模块的构建方式提出了要求(如果你在一个加载其他人编写的插件的程序上工作,这可能是不可能的 - 这些插件可能会选择静态链接到 C 运行时(。
- 将数组的地址分配给变量并删除
- vector.resize()中的分配错误
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- Win32编译器选项和内存分配
- 函数中堆分配的效果与缺少堆分配的情况
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 获取字符串的长度并将其分配给数组
- 将地址分配给本地指针后,公共对象的变量将消失
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存
- 我在二维向量中是否正确分配了内存
- 正在尝试重载二进制搜索树分配运算符
- GlobalAlloc而不是其他分配方法
- 自定义先决条件对移动分配运算符有效吗
- 我可以重新分配/覆盖std::字符串吗
- 在c++中使用动态分配的问题
- 当一个新对象被分配到它的地址时,对象是否必须被销毁
- 为什么我可以使用比分配的内存更多的内存
- 使用RAII在给定次数的迭代后重新分配资源