c++ - 尝试从 DLL 加载的派生类实例访问基类 vector 成员时程序崩溃

标签 c++ visual-c++ inheritance dll

我遇到了奇怪的崩溃。我试图将我的应用程序(基于 MFC,在 VS2005 中开发)的各个模块分离到 DLL 中。以下是我如何实现它的骨架代码:

在通用头文件中(例如base.h):

class Base {
    vector<message> messages;
    ...
    ...
};

在DLL源代码的头文件中(比如class.h):

class Derived : public Base {
private:
    int hoo();
    ...
public:
    void foo();
    int goo();
    ...
};

extern "C" __declspec (dllexport) Derived* CreateDerived();

在类.cpp中

 Derived* CreateDerived()
 {
    return new Derived;
 }

在主应用程序代码的文件中:

#include "base.h"
#include "class.h"

typedef Derived* (*DerivedCreator)();
...
...

void LoadDll()
{
    //DLL Load Code...
    ...
    ...

    DerivedCreator creator = reinterpret_cast<DerivedCreator>(::GetProcAddress(dllHandle, "CreateDerived"));

    Derived* pDerived = creator();

    pDerived->messages.push_back(message("xyz"));//Crashes here...
}

问题是当我尝试访问基类的 vector 成员时代码崩溃了。这只发生在 Release模式下。它在 Debug模式下工作正常。当我在 Release模式下从 Visual Studio 执行它时收到的错误消息是:

“Microsoft Visual Studio C 运行时库在 Samsung SSD Magician.exe 中检测到 fatal error 。

按“Break”调试程序或按“Continue”终止程序。”

但是当我直接执行发布二进制文件并将调试器附加到它时,我收到了访问冲突。此时,如果我检查调试器中的 vector ,它会显示其中的 6 位条目,但没有一个是可读的。我可以在派生指针中看到基类其余成员的正确值。

任何帮助将不胜感激。

最佳答案

跨 DLL 边界传递 STL 容器是危险的。 原因是每个模块(主应用程序和 DLL)都有自己的堆实例。如果您在 DLL 上下文中分配动态内存,然后将指针传递给应用程序并在应用程序上下文中释放该内存,则会导致堆损坏。

这正是您的示例中发生的情况。

Derived* pDerived = creator();

CreateDerived 被调用。

 Derived* CreateDerived()
 {
    return new Derived;
 }

new Derived 在 DLL 堆中分配内存。

pDerived->messages.push_back(message("xyz"));

push_back内部,为Base::messages分配了额外的内存,并且该分配是在应用程序堆上完成的。崩溃!

结论是,您需要重新考虑 DLL 接口(interface),以便仅在 DLL 内部对 vector 执行所有操作。

关于c++ - 尝试从 DLL 加载的派生类实例访问基类 vector 成员时程序崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10244770/

相关文章:

c++ - 映射<T,shared_ptr<U>>的间接迭代器

c++ - 为 C++ 编写不递增的味觉测试程序

python - 类交叉引用?

c++ - 使用 cmath 的 fmod (C++) 时的不一致

c++ - 是否可以使用 fmt 格式化带有千位分隔符的数字?

c++ - 将指针分配给引用

c++ - 非法引用结构中的非静态成员

c++ - wxWidgets (C++) 无法执行许多 wxDC.DrawPoint() 操作

scala - 使用子类的类型实现特征方法

java - SPRING BOOT - 如何从 Super POM 访问类