我在模块间内存分配/解除分配方面遇到了一些问题。 好像this帖子描述了同样的错误。
这是一段代码:
我的主要应用:
#pragma comment(lib, "mydll.lib")
__declspec(dllimport) std::shared_ptr<VOID> GetMemory(size_t size);
int wmain(int argc, wchar_t* argv[])
{
std::shared_ptr<VOID> lpMem = GetMemory(100);
return 0;
}
动态链接库代码:
__declspec(dllexport) std::shared_ptr<VOID> GetMemory(size_t size);
BOOL WINAPI DllMain(HINSTANCE, DWORD dwReason, LPVOID)
{
return TRUE;
}
std::shared_ptr<VOID> GetMemory(size_t size)
{
return std::shared_ptr<VOID>(new (std::nothrow) char[size]);
}
/MT
或 /MD
编译器标志被正确处理。并且执行不会失败。
我的问题是:为什么使用 std::shared_ptr
的解决方案可以正常工作?它改变了什么?那些在单个进程中不同的“内存管理器”(在线程 linked above 中提到)是什么?那只是一个 CRT 抽象吗?或者,CRT 可能提供一些特定的内存分配实现?
我认为,new
/malloc
/LocalAlloc
的任何调用都会导致 HeapAlloc
。我对吗?如果是这样,为什么单个进程中不同模块中的 new
/delete
调用(未用 std::shared_ptr
包装)会导致崩溃?
最佳答案
回复
” why does the solution with std::shared_ptr work properly?
因为您有未定义的行为,而 UB 包含您希望发生的事情,它确实发生了。这是 UB,因为使用 new[]
表达式创建的对象需要使用 delete[]
表达式销毁。默认情况下,shared_ptr
会通过 delete
表达式销毁。
这与是否涉及 DLL 无关。
回复
” What does [use of
shared_ptr
] change?
在 DLL 场景中,它可以捆绑调用特定于 DLL 的释放函数的删除函数。
但是,由于 shared_ptr
的控制 block 的分配,您仍然会遇到潜在的问题。这是否表现为实际问题取决于您的build设置(例如共享运行时库?)以及您使用的工具链。
回复
” And what are those "memory managers" (mentioned in the thread linked above), which are different within a single process
大概是每个 DLL 中的运行时。
如果所有 DLL 以及主程序都链接到单个公共(public) DLL 运行时,而不是静态库运行时,那么所有这些都使用相同的共享内存管理,这部分没问题。
关于c++ - 为什么 std::shared_ptr 起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35406853/