可恶的BSTR和它娘家人们---bug解决后发发牢骚

前几天曾开一贴: 《可恶的BSTR和它娘家人们》 http://blog.csdn.net/libinfei8848/archive/2010/08/06/5794318.aspx 首先要感谢几位大侠的指点,后来在分析了代码发现这样的问题: C/C++ code _bstr_t wsClauseForLink(L"MASTEROBJID='"); //pDevObjID是有值的BSTR变量 wsClauseForLink += pDevObjID; //(1) wsClauseForLink += L"' OR SLAVEROBJID='"; wsClauseForLink += pDevObjID; //(2) wsClauseForLink += L"'"; pDevObjID变量是我调用一位同事的接口方法得到的。因为他是我的领导,比较有权威。所以我一开始就没有怀疑大哥。。最后无奈的情况下找他要了代码跟了进去发现: C/C++ code STDMETHODIMP CPText::get_ObjectID( BSTR* Value) { ....//省略实现部分 *Value = (_bstr_t)val.bstrVal; return S_OK; } 他返回的是一个局部变量的值,所以在我调用的时候出现问题。 但是。。。。我今天要说的不是来当着大庭广众来数落我的领导,或者来证明自己没有错。 我是想说。。。额,BSTR还是让我感觉力不从心。。。 首先,微软为了提高COM架构的效率,系统对于BSTR提供了内存的特殊处理。即:sysfreestring的时候只是标记了bstr内存为可再分配内存,而内存里面的内容实际上没有destory掉。而这正是我纠结的根本之所在. 正常情况下,加入返回一个局部变量对象,它会在返回的时候调用其析构函数,然后回收内存: C/C++ code Object& GetObject(Object& Other) { Object tmp = Other; return tmp; } 那么我们调用这个方法的时候会第一时间认知到这个错误: C/C++ code Object &lOne = GetObject(lOther); lOne.get_XXX(xxx);//这一步必定是走不下去了,在调试的瞟一眼马上就能大喊:XX这是你的问题咯。。。 好来说说BSTR的问题: C/C++ code pObject->get_ObjectID(&pDevObjID); wsClauseForTopo += pDevObjID; wsClauseForTopo += pDevObjID; //(1) wsClauseForTopo += pDevObjID; //(2) wsClauseForTopo += pDevObjID; //(3) wsClauseForTopo += pDevObjID; //(4) 好根据BSTR的内存优化原理,执行到(1)的时候,我们总是幸运的,虽然内存已标记可重分配,但是地址还有效,值也有效。那么它心安理得的走了下去,执行到(2)通常也会人品爆发,那继续走吧,执行到(3)如果还没有问题,到了(4)甚至是一路坦荡荡那就可以去买彩票了。。。 pDevObjID这个局部变量返回的内存总会有重分配的时候,而这种BUG的出现会飘忽不定的。。。以至于我总是难以想到是调用的别人的代码而造成,翻来覆去的查看代码。。。 不知不觉中,又让我增长了debug的经验。。。。 欢迎砸砖。。。。(据说csdn大佬们分给的不多是没人愿意给回帖的,所以今天我挥泪割肉了。。。)

你可能感兴趣的:(可恶的BSTR和它娘家人们---bug解决后发发牢骚)