繁体   English   中英

释放在不同DLL中分配的内存

[英]Freeing memory allocated in a different DLL

我有一个使用DLL文件的EXE文件,该文件使用另一个DLL文件。 出现这种情况:

在DLL文件1中:

class abc
{
    static bool FindSubFolders(const std::string & sFolderToCheck, 
                               std::vector< std::string > & vecSubFoldersFound);
}

在DLL文件2中:

void aFunction()
{
    std::vector<std::string> folders;
    std::string sLocation;
    ...
    abc::FindSubFolders(sLocation, folders)
}

在发布模式下,一切正常。 但是在调试模式下,我在文件夹向量中的一个std::strings的析构函数中出现断言失败(当文件夹在aFunction结尾处超出范围时):

dbgheap.c : line 1274

/*
 * If this ASSERT fails, a bad pointer has been passed in. It may be
 * totally bogus, or it may have been allocated from another heap.
 * The pointer MUST come from the 'local' heap.
 */
_ASSERTE(_CrtIsValidHeapPointer(pUserData));

我假设这是因为内存已经分配在DLL文件1的堆上,但是在DLL文件2中被释放。

dbgheap.c的注释似乎非常坚持认为这是一个问题。

为什么这是一个问题,如果我忽略它似乎工作正常? 是否有一种非断言失败的方式来做到这一点?

正如肖恩已经说过的那样,发布版本只是忽略了删除语句,所以你可以期待的最好是内存泄漏。

如果您可以控制两个DLL文件的编译方式,请确保使用运行时库的多线程调试DLL(/ MDd)或多线程DLL(/ MD)设置。 这样,两个DLL文件将使用相同的运行时系统并共享同一个堆。

缺点是您需要将运行时系统与您的应用程序一起安装(Microsoft提供了一个安装程序)。 它可以在您的开发机器上正常工作,因为Visual Studio也安装了该运行时系统,但在新安装的机器上它将报告缺少的DLL文件。

最有可能的是,发布版本具有相同的问题,但发布版本没有断言。 他们只是忽略了这个问题。 你可能永远不会看到问题。 或者您可能会看到数据损坏。 或者你可能会看到崩溃。 也许只有您的用户才会遇到您无法重现的错误。

不要忽略CRT断言。

您应该始终使用适当的解除分配器(与开始时使用的分配器匹配的解除分配器)。 如果您在DLL文件中使用静态CRT库,则DLL文件使用不同的堆。 你不能在整个堆中释放内存。 使用相同的堆分配和释放内存块。

如果您在DLL文件中使用共享CRT库,那么它们应该使用相同的堆,您可以在一个DLL文件中分配并在另一个DLL文件中取消分配。

正如其他人所说,可以通过确保两个模块之间共享CRT来解决问题。 但是有一些常见的情况是这个合同难以执行。

原因是如果EXE和DLL没有链接到相同的CRT 版本 (如6.0,7.0,8.0),确保链接共享CRT将不起作用。 例如,如果您使用已在VC6.0中构建的DLL并尝试在VS2010中使用EXE版本,则会遇到与以前相同的问题。 CRT的两个版本将在您的进程中加载​​,并且每个版本都使用自己的堆进行分配,无论您的EXE和DLL使用“共享”CRT,它们都不会相同。

API的一个更好的做法是确保在一侧分配的对象也在同一侧被销毁。 我知道这听起来很丑,但这是确保DLL保持二进制兼容的唯一方法。

如果应用程序或一个(或多个)DLL文件链接到标准库的静态版本,则这只是一个问题。 大约十年前,MS发布了标准库的共享库版本。 这是因为标准库的每个版本都将构建自己的内部堆,因此需要使用多个堆,您必须将内存释放到正确的堆中。 通过使用标准库的共享版本,它们都使用相同的堆。

现在是应用程序的标准做法,应该构建所有DLL文件以使用标准库的动态版本。

上面唯一的警告是,如果您创建自己的堆并从此堆分配内存。 但这是一个非常专业的程序,只在极少数情况下才能完成(如果你理解足够使用它,那么你就不会出现这个问题)。

暂无
暂无

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

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