2011-10-07 228 views
3

我有一些代码需要放在公用库dll中。这个代码,类CalibrationFileData,作为当前项目的一部分构建时,工作得很好。但是,如果公用库中内置了CalibrationFileData,则程序崩溃,提到堆损坏。使用DLL代码时堆损坏

我已经确保所有的分配和释放都在类中,并带有适当的访问器等等。但是,问题不会消失。为防万一,它有时会传递对的向量,绝对不是普通的旧数据,但矢量操作只能通过访问器进行,所以不应该在模块间进行任何分配。

我错过了什么?

编辑:的载体是这些:

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

我不应该需要担心深层副本,因为他们是不分配的堆,对不对?顺便说一句,我试图使用指针作为向量,如上所述,以回避这个问题,但它并没有改变。

+2

我担心的载体本身。因为它是一个模板,DLL和EXE可以有不同的向量代码实例。这可能是Trajanfoe暗示的 - 不确定。此外,什么对的矢量?对包含指向堆分配对象的指针吗? – Steve314

回答

1

您是否确定当您在方法中取得vector对象内容的所有权时,将其深度复制到实例变量中?

4

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

+0

+1第二,我特别是在使用标准模板库时。 –

+0

/MT还不够 - 它仍然会产生内存分配器的两个“实例”。/MD(或/ MDd)是一种方法。 –

0

你应该检查矢量对象内心深处的副本,它与deepcopy的属于我觉得

0

它可以在这两个项目_SECURE_SCL定义的值不同?

0

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

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

0

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

0

你应该之间紧密耦合松耦合DLL小号区分。

紧耦合DLL什么恶意那

DLL是建立具有完全相同的编译器版本,包装和 调用约定设置,库选项作为应用程序,并 两个动态链接到运行时库(/MD编译器选项)。 这使您可以传递对象来回包括STL容器, 其他模块中分配DLL对象从应用程序中,获得从基本 类,做到这一切你可以 不使用DLL秒。缺点是您不能再使用 部署DLL而不依赖主应用程序。两者必须建立在一起 。 DLL只是为了提高您的进程启动时间 和工作集,因为应用程序可以在 加载DLL(使用/delayload链接器选项)之前开始运行。编译时间 也比单个模块更快,特别是在使用整个程序 优化时。但是优化不会发生在整个 应用程序-DLL边界上。并且任何不重要的更改仍然需要重建两者。

松散耦合DLL案,然后

当导出DLL函数,这是最好的,如果它们只接受积分 数据类型,即int或指针。

参考,例如为字符串,然后:

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

最后,关于内存分配,则:

切勿使用由DLL外的DLL自己 功能分配的内存,也不会被认为有自己的 构造函数值的结构/传析构函数。

参考

Heap corruption when returning from function inside a dll

Can I pass std::string to a DLL?