C++ 为什么std::shared\u ptr工作?

C++ 为什么std::shared\u ptr工作?,c++,memory-management,shared-ptr,C++,Memory Management,Shared Ptr,我在模块间内存分配/释放方面遇到一些问题。 波斯特似乎描述了同样的错误 下面是一段代码: 我的主要申请: #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

我在模块间内存分配/释放方面遇到一些问题。 波斯特似乎描述了同样的错误

下面是一段代码:

我的主要申请:

#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;
}
#pragma注释(lib,“mydll.lib”)
__declspec(dllimport)std::shared_ptr GetMemory(size_t size);
int wmain(int argc,wchar_t*argv[])
{
std::shared_ptr lpMem=GetMemory(100);
返回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]);
}
\u declspec(dllexport)std::shared\u ptr GetMemory(size\u t size);
布尔WINAPI DllMain(HINSTANCE、DWORD dwReason、LPVOID)
{
返回TRUE;
}
std::共享内存(大小)
{
返回std::shared_ptr(新的(std::nothrow)字符[size]);
}
已正确处理
/MT
/MD
编译器标志。执行也不会失败

我的问题是:为什么使用
std::shared\u ptr
的解决方案能够正常工作?它改变了什么?在单个进程中不同的“内存管理器”(在线程中提到)是什么?这仅仅是一个CRT抽象吗?或者,CRT是否提供了一些特定的内存分配实现

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

为什么使用std::shared\u ptr的解决方案工作正常

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

这与是否涉及DLL无关


共享ptr的[使用]发生了什么变化

在DLL场景中,可以绑定一个调用特定于DLL的释放函数的deleter函数

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


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

可能是每个DLL中的运行时

如果所有DLL以及主程序都链接到单个公共DLL运行时,而不是静态库运行时,则所有DLL和主程序都使用相同的共享内存管理,并且该部分正常。

Re

为什么使用std::shared\u ptr的解决方案工作正常

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

这与是否涉及DLL无关


共享ptr的[使用]发生了什么变化

在DLL场景中,可以绑定一个调用特定于DLL的释放函数的deleter函数

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


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

可能是每个DLL中的运行时


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

非常感谢您的回答。是的,我看到了未定义行为的问题。我不应该匆忙地拿出一个代码样本。那么“特定于DLL的释放函数”呢?为什么它是特定于dll的。特定于DLL的原因是什么?@MAKAKOKO:主要是DLL可以链接到与此过程中的主程序或其他DLL不同的运行时库(静态或作为DLL)。当运行库通过DLL静态链接时,它会自动不同,因为DLL实例有自己的变量来跟踪内存区域等。请注意,Unixland共享库的情况不同。非常感谢您的回答。是的,我看到了未定义行为的问题。我不应该匆忙地拿出一个代码样本。那么“特定于DLL的释放函数”呢?为什么它是特定于dll的。特定于DLL的原因是什么?@MAKAKOKO:主要是DLL可以链接到与此过程中的主程序或其他DLL不同的运行时库(静态或作为DLL)。当运行库通过DLL静态链接时,它会自动不同,因为DLL实例有自己的变量来跟踪内存区域等。请注意,Unixland共享库的情况不同。