为什么std :: shared_ptr有效?

时间:2016-02-15 10:25:40

标签: c++ memory-management shared-ptr

我在模块间内存分配/释放方面遇到了一些问题。 好像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;
}

Dll代码:

__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的解决方案能够正常运行?它有什么变化?什么是那些&#34;内存管理器&#34; (在线程linked above中提到),在单个进程中是不同的?那只是一个CRT抽象吗?或者,CRT可能提供了一些特定的内存分配实现吗?

我认为,new / malloc / LocalAlloc的任何来电都会导致HeapAlloc。我对吗?如果是这样,为什么new / delete - 在一个进程中的不同模块中调用(不包含std::shared_ptr)会导致崩溃?

1 个答案:

答案 0 :(得分:3)

RE

  

为什么std :: shared_ptr的解决方案能够正常运行?

因为您有未定义的行为,并且UB包含您希望会发生的事情,所以会发生。它是UB,因为使用new[]表达式创建的对象需要使用delete[]表达式进行销毁。默认情况下,shared_ptr会通过delete表达式销毁。

这与DLL是否涉及无关。

RE

  

[使用shared_ptr]会有什么变化?

在DLL场景中,它可以捆绑一个调用特定于DLL的释放函数的删除函数。

但是,由于分配了shared_ptr的控制块,您仍然可能会遇到问题。这是否表现为实际问题取决于您的构建设置(例如共享运行时库?)以及您正在使用的工具链。

RE

  

那些”内存管理器“(在上面链接的线程中提到)是什么,它们在一个进程中是不同的

大概是每个DLL中的运行时。

如果所有DLL和主程序都链接到单个公共DLL运行时,而不是静态库运行时,那么所有DLL都使用相同的共享内存管理,那部分就可以了。