在VC6 DLL中使用auto_ptr会导致崩溃

时间:2010-04-16 02:24:51

标签: c++ visual-c++

// dll
#include <memory>

__declspec(dllexport) std::auto_ptr<int> get();

__declspec(dllexport) std::auto_ptr<int> get()
{
    return std::auto_ptr<int>(new int());
}

// exe
#include <iostream>
#include <memory>

__declspec(dllimport) std::auto_ptr<int> get();

int main() {
    {
        std::auto_ptr<int> x = get();
    }
    std::cout << "done\n";
    getchar();
}

以下代码在VC9下运行完全正常。但是,在VC6下,我会遇到以下消息立即崩溃。

  

Debug Assertion失败!

     

程序:   C:\项目\ use_dynamic_link \调试\ use_dynamic_link.exe   文件:dbgheap.c行:1044

     

表达式:   _CrtIsValidHeapPointer(pUserData)

是不允许在VC6下导出auto_ptr?

通过DLL导出STL集合类是一个已知问题。

Access Violation When Accessing an STL Object Through A Pointer or Reference In A Different DLL or EXE

然而,我谷歌周围并没有看到任何提及std :: auto_ptr。

任何解决方法?

4 个答案:

答案 0 :(得分:4)

DLL有自己的堆,所以你必须确保你是新的并从同一个上下文中删除。

答案 1 :(得分:1)

我的第一个猜测是VC9中的exe和dll项目被设置为CRT作为共享dll的目标,而一个或两个VC6项目都是针对静态CRT(非dll)。 / p>

或者,dll和exe都针对共享CRT dll的不同版本(因此它们实际上使用了2个不同的CRT)。

在VC6中,检查C / C ++项目属性的代码生成类别中的运行时库选项。确保exe和dll都定位相同的DLL库选项。

答案 2 :(得分:1)

您违反了ODR(一个定义规则),并且很可能内联成员函数 - 因为它们内联了两个不同的std::auto_ptr定义,您会得到未定义的行为。

最重要的是,正如Eddy指出的那样,当auto_ptr::~auto_ptr释放被保持的对象时,它将在EXE中调用operator delete,而不是在调用operator new的DLL中调用__declspec(dllexport)。这种不匹配也会导致崩溃。

一般来说,导出已实现的类(仅由纯虚函数组成的接口类,并为构造导出免费的工厂函数)是非常脆弱的,然后你不要在类上使用{{1}},仅限于工厂功能。

答案 3 :(得分:0)

行。我意识到了根本原因。它是由

引起的

DLL内存管理器混音

DLL memory manager mixup

  1. 从DLL分配内存

  2. 将指针返回EXE

  3. 尝试从EXE中删除指针

  4. 如果我们动态链接到运行时库(在选项C / C ++ - &gt;代码生成 - &gt;使用运行时库),

    步骤(3)将只能正常工作

    如果我们静态链接到运行时库,DLL使用的内存管理器可能与EXE使用的内存管理器不同。