玩心未泯

卡尔斯希普拉斯

C++博客 首页 新随笔 联系 聚合 管理
  19 Posts :: 0 Stories :: 98 Comments :: 0 Trackbacks

今天写程序的时候碰到一个问题,调试的时候总是报错Heap corruption detected。一直没碰到过这样的问题,所以实在不知道如何下手。后来偶然一次注释掉一个释放语句,就没报错了Heap corruption detected了(但是报memory leak),才发现原来这个释放有问题。我的一个函数调用中,开始的时候分配了一个char数组,结束的时候释放这个数组空间,看起来完全是没有问题的,居然会引发Heap corruption detected。代码大体如下:
 
char* pCmd = new char[len+1];   // len has got value before
memset( pCmd, 0, len+1);
.........
for(int i=0;i<len;i++) {
      ........      //获取一个str内容形如:"1A", "0F"
      sscanf(str, "%02X", &pCmd[i]);
}
.....
delete [] pCmd;

找到问题的所在,再分析代码才发现了这其中一个很隐蔽的问题,就是那句sscanf,由于第二个参数用的是"%02X",那么对它而言,最后一个参数就是一个指向int类型的指针了,而我给的实际是一个char的指针。
如果上面的循环只进行到i<len-2,或者pCmd的size扩大到len+3,都可以避免heap corruption。
后来我干脆用了一个零时的int型变量来完成这个工作。

要分析这个问题,太理论化的我将不上来,应该是sscanf调用的过程中,由于pCmd分配到的空间不足,因此引发了新的分配,pCmd不再是像声明的那样一个len+1大小的char数组,因此直接调用delete [] pCmd就会引发heap corruption了。到底咋回事,也许还要高人来讲讲。

posted on 2007-04-10 17:39 SuperPlayeR 阅读(13289) 评论(3)  编辑 收藏 引用 所属分类: C/C++

评论

# re: 一个不小心引发的Heap corruption 2007-04-11 19:50 Paradoxiology
从VS.Net之后,CRT带的malloc都会在每次分配的内存块的前端和末尾增添一些额外的调试信息,每次free它们的时候都会检测一下,如果改变了就说明内存溢出之类的情况发生了。
所以说heap corruption的引发是因为使用sscanf的时候覆盖了调试信息,sscanf本身是不会分配内存的。  回复  更多评论
  

# re: 一个不小心引发的Heap corruption 2007-04-11 23:41 nick
to Paradoxiology:
不是从 vs.net 开始的吧. 至少 vc6 就有了.  回复  更多评论
  

# re: 一个不小心引发的Heap corruption 2011-07-18 16:05 啊啊
应该是VC6 就有了,这个应该是一种基本的内存检测手段  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理