一次vector析构异常的思考

转载 2011年01月24日 19:10:00

关键字:exe、dll、STL string、local heap。

  一个结构体 ITEM 中包含了多个 string 类型字段,在 exe 中的 ExeFunc 中定义 ITEM 变量 item,传 item 的引用到 DllFunc 函数中,DllFunc 是一个 dll 的导出函数,负责从文件中读取一些数据到 ITEM 结构中。在 ExeFunc 结束的时候 string 异常了,提示堆内存损坏。排除法发现多个 string 字段中只有一个引发了异常,其它的都没有问题,觉得很奇怪。string 异常的字段赋值的字符串大于 16 个字符(string 默认是15 还是 16 个 byte 来着)其它的都小于 16 个字符,显然是 string 对象重新分配内存了。

  查看内存也没有发现异常情况,怀疑 string 有问题,于是另外建了个工程测试 string,单个 exe 或者模拟工程中建立一个 dll 赋值给引用 string 变量都正常,而且字符数大于 16 个。

  跟踪定位到 _CrtIsValidHeapPointer ,注意到 dbgheap.c 文件中 _CrtIsValidHeapPointer 处注释:

         /*
         * If this ASSERT fails, a bad pointer has been passed in. It may be
         * totally bogus, or it may have been allocated from another heap.
         * The pointer MUST come from the 'local' heap.
         */

         _ASSERTE(_CrtIsValidHeapPointer(pUserData));

  搜索到一些关于本地堆(local heap)的文章,才明白是因为 dll 如果静态链接了运行时库,dll 就会拥有独立于应用程序堆(也称作local heap)的运行时堆实例。此时在 dll 外部就不能访问此 local heap,所以也就有上面所出现的异常啦。MSDN 中也有介绍:

  The _CrtIsValidHeapPointer function is used to ensure that a specific memory address is within the local heap. The local heap refers to the heap created and managed by a particular instance of the C run-time library. If a dynamic-link library (DLL) contains a static link to the run-time library, it has its own instance of the run-time heap, and therefore its own heap, independent of the application's local heap. When _DEBUG is not defined, calls to _CrtIsValidHeapPointer are removed during preprocessing.

  查找这个问题浪费了不少的时间,解决办法就是在编译 dll 时动态链接运行时库( VS2005 下动态链接 MFC 库默认就是动态链接运行时库,如果更改静态链接 MFC 库,运行时库的链接方式也跟着改变为静态的),并且 exe 中也要使用相同的链接方式才行。这或许是有时候改变 MFC 库的链接方式会引起一些莫名错误的原因吧;对了在 _CrtIsValidHeapPointer 内部也有这样的注释:

         /*
         * Go through the heap regions and see if the pointer lies within one
         * of the regions of the local heap.
         *
         * Pointers from non-local heaps cannot be handled. For example, a
         * non-local pointer may come from a DLL that has the CRT linked-in.
         *
         */

  结论:应用程序使用的 dll 库在链接时尽量使用相同的链接方式,大多数情况下不同的链接方式不会出现问题,但有少数情况总是存在的。额要是在第一时间看清楚明了的 MSDN 就不会走N多的弯路了:(

 

 

原文出处:http://hi.baidu.com/anowsober/blog/item/9c1abcd95d20b4ee38012f6b.html

Dll中运用vector的堆栈崩溃

今天在调试程序的时候遇到了这个问题。 先给出出问题的代码: [.dll] vector getPerList(){return _perList;} vector getGrpList(){ret...
  • han6771306
  • han6771306
  • 2014年04月15日 23:43
  • 1015

opencv2.0在mfc中使用vector崩溃问题

首先我描述一下我的机器配置环境 OpenCV2.4.10+vs2008+vs2010+vs2013,由于Opencv2.4.10已经完成了vc10以上的配置库编译。当我使用opencv使用findco...
  • w1w1bbbb
  • w1w1bbbb
  • 2014年12月12日 19:16
  • 1370

如何解决vector 析构异常 opencv Assert _CrtIsValidHeapPointer

vector 析构异常 opencv Assert _CrtIsValidHeapPointer
  • lanbing510
  • lanbing510
  • 2014年10月29日 14:26
  • 5398

遇到该Vector析构时_CrtIsValidHeapPointer(pUserData) 的bug已经好几天了

问题描述:训练程序。当样本数为pos500 neg500时,训练了2天两夜17个节点了都没问题。当样本数改为pos3800 neg300时,出现了问题,在训练完弱分类器的一个维度准备返回时崩溃,提示断...
  • zdl1016
  • zdl1016
  • 2010年03月15日 11:47
  • 1756

C++语句:vector<string>v_string;是什么意思?v_string代表什么?

ector是c++标准库的一个容器,如果你学过数据结构就知道有数组,线性表,链表之类各种东西吧,vector实际上就是数组。 string是c++标准库的字符串类型 v_string看上去在这里只...
  • zangchaodotcnatgmail
  • zangchaodotcnatgmail
  • 2015年09月19日 14:29
  • 1217

C++ vector变量等导致内存泄露问题的解决方法

之前在做一个音频特征提取的批量处理程序,老是出现内存泄露问题,用Visual Leak Detector(VLD)工具做了下检测,检测出了一些问题,解决后还是会有问题。之后继续排查,因为我的代码中,大...
  • cdjcong
  • cdjcong
  • 2016年03月09日 21:26
  • 3647

面试宝典上的vector二次析构问题

今天看面试宝典CHAP 9 STL模板与容器时,有一道面试题讲vector二次析构出错的,看了解答还不是很明白,经过google之后终于搞清楚了,记录如下: 面试宝典上的vector二次析构问题: ...
  • a936676463
  • a936676463
  • 2015年03月19日 18:25
  • 620

vs 中opencv vector析构问题

来源:[VS+OpenCV] 程序运行过程正常,当跳出函数是出现断言错误vs2013 opencv vector析构时出错具体内容: 自己来回答了,原因其实很简单,却容易想不到。 出错的根本...
  • liuzw1995
  • liuzw1995
  • 2017年04月27日 10:50
  • 354

Android Vector曲折的兼容之路

Android Vector曲折的兼容之路 两年前写书的时候,就在研究Android L提出的Vector,可研究下来发现,完全不具备兼容性,相信这也是它没有被广泛使用的一个原因,经过Google的...
  • u010335298
  • u010335298
  • 2016年07月06日 17:15
  • 12583

使用swap来释放vector的内存

先说明如何使用swap来释放 vector 的内存,然后再说明在释放过程中发生了什么。释放操作如下: void func() { vector vec(2,3); vec.swap(vector(...
  • Virtual_Func
  • Virtual_Func
  • 2015年09月18日 09:46
  • 756
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:一次vector析构异常的思考
举报原因:
原因补充:

(最多只允许输入30个字)