本站首页    管理页面    写新日志    退出


«July 2025»
12345
6789101112
13141516171819
20212223242526
2728293031


公告

☆★☆★☆★☆★☆★☆
生活的点点记录,以及一些体会...........

喜欢是淡淡的爱,爱是深深的喜欢.

时间会见证一切.......................

欢迎大家指出错误,共同进步..........

期待中..............................

☆★☆★☆★☆★☆★☆


我的分类(专题)

日志更新

最新评论

留言板

链接

世纪音频

 

 


Blog信息
blog名称:
日志总数:162
评论数量:312
留言数量:0
访问次数:940349
建立时间:2005年5月17日




free指针时遭遇_CrtIsValidHeapPointer
文章收藏

oceanblue 发表于 2008/5/14 8:58:03

malloc和free在教材里不知讲了多少,今天实际用到一处,就出问题了。 案发现场是我用VC++在WINXP下编程,先看这一段代码{    BYTE    *pBuffer;    pBuffer = (BYTE *)malloc(64);    pBuffer = pBuffer + 32;    free(pBuffer);    pBuffer = NULL;}  //第一段先声明一个指针,然后分配64字节给它。操作指针向后移动32字节,最后把这个指针free掉并设为NULL。这样虽然操作时的数据还留在内存区域里,但已经没有指针指向该区域,数据可以被后面的程序覆盖了。看起来没错吧?恩恩好象是没错, 抓了三个同事来问,全票通过. 嘿嘿,被偶骗了,我得意地笑~~~但在实际上呢, 运行时会跳出这个警告 500)this.width=500'> 而如果把代码改成{    BYTE    *pBuffer;    pBuffer = (BYTE *)malloc(64);    pBuffer = pBuffer + 32;    pBuffer = pBuffer -32;    free(pBuffer);    pBuffer = NULL;}  //第二段代码就没错了。李博士的解释是:malloc的时候系统创建了一个链表之类的东西,里面包含了起始地址和长度;而free的时候根据参数中的指针进行判断,如果该指针符合链表中某一节的起始地址,那么就把这一节free掉,如果去free一个不在链表中的地址,就出错啦。 比较好的处理方式是这样{    BYTE    *pBuffer;    BYTE    *pBytePtr;    pBuffer = (BYTE *)malloc(64);    pBytePtr = pBuffer;    pBytePtr = pBytePtr + 32;    free(pBuffer);    pBuffer = NULL;    pBytePtr = NULL;}  //第三段代码 即保留malloc时候的初始地址,然后赋给另外一个临时指针。操作时使用后者。free的时候把保留的起始指针free掉,而临时指针只是个变量,置空就可以了。 文章到这里似乎就应该写完了,不过由于johnathan的帮忙, 突然有了下文。 注意警告框中的_CrtIsValidHeapPointer,在MSDN上查到这个函数的说明为: Verifies that a specified pointer is in the local heap (debug version only). int _CrtIsValidHeapPointer(const void *userData); Parameter:userData  Pointer to the beginning of an allocated memory block. Return Value:_CrtIsValidHeapPointer returns TRUE if the specified pointer is in the local heap. Otherwise, the function returns FALSE. 也就是说仅在debug版本中检查free参数是否为the beginning of an allocated memroy block. 那么就编译一个release版本,果然,运行通过, 没弹出什么警告或错误。但运行通过不等于正常无误, 这就是无声无息导致内存泄露的罪魁祸首. 即使release版里面也应该free起始地址. 那么结论就是:free掉非malloc起始地址的指针,在debug版本中会出错警告,而在release版本中不会弹出警告但仍然是有错的。所以,还是推荐使用第三段代码的用法。 500)this.width=500'>


阅读全文(2023) | 回复(0) | 编辑 | 精华
 



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.047 second(s), page refreshed 144757884 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号