您的位置:首页 > 其它

TinyXml Print 函数 Bug

2016-03-22 13:33 246 查看
最近做一个项目,用到了TinyXml操作XML,有一个地方需要用print函数把XML文本打印出来,代码如下:

m_pDbCfg->trees[m_pDbCfg->treeCount-1].cbuffer = (char*)malloc( MAX_BUFFERSIZE );
int idx = 0;
int isize = MAX_BUFFERSIZE;//由于无法预计最大长度,<span style="font-family: Arial, Helvetica, sans-serif;">看了一下Print函数,打印时对长度做出了判断,当长度不够时,realloc了一个新的大小,便</span>将<span style="font-family: Arial, Helvetica, sans-serif;">MAX_BUFFERSIZE定义为512,</span>
treeElement->Print( m_pDbCfg->trees[m_pDbCfg->treeCount-1].cbuffer, &idx, &isize, 0 );


程序结束时,我打算free掉m_pDbCfg->trees[m_pDbCfg->treeCount-1].cbuffer,问题来了,有时会崩溃,有时正常,真是让人觉得莫名其妙,找同事看了看,一开始在外边自己代码找问题,感觉TinyXml这个库辣么多人用,应该不会出问题嘛。但是,外边没找到问题,后来调试到Print函数里边,突然发现,realloc 存在问题,把代码贴出来,如下(代码太多就不全部贴出来了,能说明问题就行):

void TiXmlElement::Print( char* cbuffer, int *idx, int *size, int depth ) const
{
int i;
for ( i=0; i<depth; i++ )
{
sprintf( &cbuffer[*idx], "    " );
*idx += strlen("    ");
if(*idx > *size-128)
{
*size += 1024;
cbuffer = (char *)realloc(cbuffer, *size);
}
}
<span style="font-family: Arial, Helvetica, sans-serif;">}</span>


问题是什么呢?那就是realloc之后,指针的地址可能会发生变化,cbuffer = (char*)realloc(cbuffer, *size);也即是说,此时返回的cbuffer(局部变量)与实参不一致,至于原因可见realloc函数介绍,如下:
原型::void *realloc(void *mem_address, unsigned int newsize);
功能:先判断当前的指针是否有足够的连续空间,如果有,扩大mem_address指向的地址,并且将mem_address返回,如果空间不够,先按照newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address所指内存区域(注意:原来指针是自动释放,不需要使用free),同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。
所以,如果空间不够,那么m_pDbCfg->trees[m_pDbCfg->treeCount-1].cbuffer指针所指内容就是无效的,当我使用m_pDbCfg->trees[m_pDbCfg->treeCount-1].cbuffer去free时,程序就会崩溃。
解决:可以把print函数的参数cbuffer定义为指针的指针,或者指针的引用,这样,realloc产生的地址就能赋值给实参了,由于指针还要解引用,改动代码太多,本人将cbuffer改为指针的引用,问题成功解决。
感慨:这么成熟的一个库,都会出这样的问题,一定要敢于怀疑,大胆假设,小心求证。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: