c++ - 为什么 std::shared_ptr 起作用?

标签 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;
}

动态链接库代码:

__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/

相关文章:

c++ - 如何使语言友好功能降低?

c++ - 以PHP方式使用C++的Web开发环境

c - 在堆上分配小内存块?

c++ - 在 dll 接口(interface)中使用 shared_ptr

c++ - 稀疏矩阵加法条件

c++ - 对于以下用途,vector 和 deque 之间最有效的是什么?

.net - 限制 .Net CLR 内存使用

c++ - 自定义数据大小以进行内存对齐

c++ - 在 C++ 中对共享指针的 vector 进行排序

c++ - 如何复制 shared_ptr 的 vector ?