【问题标题】:Why does the std::shared_ptr work?为什么 std::shared_ptr 工作?
【发布时间】:2016-02-15 10:25:40
【问题描述】:

我在模块间内存分配/释放方面遇到了一些问题。 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 的解决方案可以正常工作?它有什么变化?那些在单个进程中不同的“内存管理器”(在线程linked above 中提到)是什么?这只是一个 CRT 抽象吗?或者,可能是 CRT 提供了一些特定的内存分配实现?

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

【问题讨论】:

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


    【解决方案1】:

    回复

    为什么使用 std::shared_ptr 的解决方案可以正常工作?

    因为你有未定义的行为,而 UB 包括你希望发生的事情,发生了。它是 UB,因为使用 new[] 表达式创建的对象需要使用 delete[] 表达式销毁。 shared_ptr 默认通过 delete 表达式销毁。

    这与是否涉及 DLL 无关。


    回复

    [shared_ptr] 的使用有何变化?

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

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


    回复

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

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

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

    【讨论】:

    • 非常感谢您的回答。是的,我看到了未定义行为的问题。我不应该急于提供代码示例。那么“特定于 DLL 的释放函数”呢?为什么它是特定于 dll 的。 DLL-specific 的原因是什么?
    • @MAKAKOKO:主要是DLL可以链接到与此进程中的主程序或其他DLL不同的运行时库(静态或作为DLL)。当运行时库由 DLL 静态链接时,它会自动不同,因为 DLL 实例有自己的变量来跟踪内存区域等。请注意,这对于 Unixland 共享库是不同的。
    猜你喜欢
    • 2011-08-20
    • 2017-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-11
    • 1970-01-01
    • 2015-07-23
    相关资源
    最近更新 更多