【问题标题】:Heap corruption when using DLL code使用 DLL 代码时堆损坏
【发布时间】:2011-12-03 00:45:01
【问题描述】:

我有一些代码需要放在公共库 dll 中。这段代码是一个类CalibrationFileData,当它作为当前项目的一部分构建时,它工作得非常好。但是,如果CalibrationFileData 内置在公共库中,程序就会崩溃,并提到堆损坏。

我已确保所有分配和解除分配都发生在类中,并使用适当的访问器等。不过,问题不会消失。为了以防万一,我有时会传递成对的向量,绝对不是普通的旧数据,但向量操作仅通过访问器发生,因此不应该跨模块进行任何分配。

我缺少什么吗?

编辑:向量如下:

std::vector<std::pair<CvPoint2D32f, CvPoint3D32f>>* extrinsicCorrespondences;
std::vector<int>* pointsPerImage;

我不应该担心深拷贝,因为它们不是堆分配的,对吧?顺便说一句,如上所述,我尝试使用 pointers 指向向量来回避问题,但无论如何它并没有产生任何影响。

【问题讨论】:

  • 我担心向量本身。因为它是一个模板,所以 DLL 和 EXE 可以有不同的矢量代码实例。这可能是 trajanfoe 暗示的 - 不确定。另外,什么向量对?这些对是否包含指向堆分配对象的指针?

标签: c++ debugging dll heap-memory heap-corruption


【解决方案1】:

您确定当您在您的方法中获得vector 对象的内容所有权时,您正在将它们深度复制到您的实例变量中?

【讨论】:

    【解决方案2】:

    检查库和可执行文件之间的编译标志匹配。例如,在 Windows 上确保您使用相同的 C 运行时库 (CRT)(/MD 与 /MT)。检查来自链接器的警告。

    【讨论】:

    • +1 我支持这一点,尤其是在使用标准模板库时。
    • /MT 是不够的——它仍然会产生内存分配器的两个“实例”。 /MD(或 /MDd)是一种方法。
    【解决方案3】:

    你应该检查向量对象内的深拷贝,我认为它与深拷贝有关

    【讨论】:

      【解决方案4】:

      两个项目中为 _SECURE_SCL 定义的值可能不同吗?

      【讨论】:

        【解决方案5】:

        您可能错过了尝试释放您的 DLL 分配的内存的客户端代码,反之亦然。

        也许最简单的做法是确保客户端和 DLL 使用相同的内存分配器。不仅是同一种,而且是分配器的同一个实际“实例”。在 Visual C++ 上,这很容易通过客户端和 DLL 使用“多线程调试 DLL (/MDd)”或“多线程 DLL (/MD)”运行时库来实现。 p>

        【讨论】:

          【解决方案6】:

          在命令行选项中,在 Visual Studio 中删除此 _SECURE_SCL。大多数情况下,此崩溃是由详细信息之间的 _SECURE_SCL 不匹配引起的。更多细节可以在这里找到:http://kmdarshan.com/blog/?p=3830

          【讨论】:

            【解决方案7】:

            你应该区分紧耦合松耦合DLLs。

            紧耦合 DLLs 表示

            DLL 使用完全相同的编译器版本构建,打包和 调用约定设置,作为应用程序的库选项,以及 两者都动态链接到运行时库(/MD 编译器选项)。 这使您可以来回传递对象,包括 STL 容器, 从应用程序内部分配DLL 对象,派生自基础 另一个模块中的类,做你能做的一切 不使用DLLs。缺点是不能再 独立于主应用程序部署DLL。两者都必须 一起建造。 DLL 只是为了改善您的流程启动时间 和工作集,因为应用程序可以在之前开始运行 加载DLL(使用/delayload链接器选项)。构建时间 也比单个模块快,尤其是在整个程序时 使用了优化。但优化不会发生在整个 应用程序-DLL 边界。任何不平凡的改变仍然会 两者都需要重建。

            如果是松散耦合DLLs,那么

            导出 DLL 函数时,最好只接受整数 数据类型,即int 或指针。

            例如,参考字符串,则:

            当您需要传递字符串时,将其作为const char * 传递。当你 需要DLL函数返回一个字符串,传递给DLL一个char * 指向预分配缓冲区的指针,DLL 将在其中写入 字符串。

            最后,关于内存分配,那么:

            永远不要在DLL 自己的之外使用由DLL 分配的内存 函数,并且从不传递具有自己的值结构 构造函数/析构函数。

            参考文献

            Heap corruption when returning from function inside a dll

            Can I pass std::string to a DLL?

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-03-31
              • 1970-01-01
              • 2012-11-20
              • 2014-05-04
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多