0

已解决:经过几次实验,这似乎是可能的。

我想知道是否可以通过让内存管理器伴随重载内存函数(new、delete、delete[]、malloc()...)并负责任何分配/释放来避免常见的跨 dll 分配/释放问题这可以在程序的任何地方发生,从而确保一致性。

假设 a.dll 包含内存管理器,例如:

class EXPORT MemoryManager
{
    static void* Allocation( size_t uiSize );
    static void  Deallocation( void* pAllocated );
};

inline void* operator new( size_t uiSize )
{
    return MemoryManager::Allocation( uiSize );
}

inline void operator delete( void* pAllocated )
{
    MemoryManager::Deallocation( pAllocated );
}

以及其他任何地方,包括 b.dll:

int* piDummy = ExternalDllFunctionCallingNew();
delete piDummy;

它会解决问题吗?

4

1 回答 1

1

你可能误解了这个问题。问题不仅在于几个 DLL,还在于混合了不同的内存管理器。具体来说,当用于释放某个块的分配器与最初分配该块的分配器不同时,就会出现问题。一个常见的问题是两个分配器期望不同的元数据布局(例如,块的大小存储在哪里)。您的“解决方案”只是在组合中添加了另一个内存管理器,因此它只会增加由不同内存管理器完成的分配和释放的更多可能性。编辑: 如果你能强制执行所有内存分配和释放使用限制在单个 DLL 中的内存管理器,它可能会正常工作。但是,正如 Hans Passant 在评论中指出的那样,如果您可以强制执行,您很可能也可以强制所有组件使用相同的 CRT 版本。

DLL 仅与此问题相关,因为大多数内存分配是通过 C 或 C++ 运行时提供的内存管理器进行的,并且根据 DLL 的编译方式,它们通常不同(甚至比其他运行时库更是如此)。如果您小心,您可以成功地跨 DLL 边界分配和取消分配,并且您可以在单个 DLL 中遇到类似的问题。

于 2013-05-12T13:05:02.143 回答