goto的坑

调试了一个crash,很诡异,程序是崩在一个线程函数中调用一个对象的虚函数——vptr被改了。

Review了这个对象所有引用的代码没能发现问题,只能操起windbg调试了,好在这个问题比较容易重现。调试中发现这个对象被正确的构造了之后一直没有释放,却在另一个模块中通过new申请到了同一块内存,因此造成vptr等内容被修改,线程函数中再调用其虚函数就崩溃了。

通过ba r 4 0xXXXXXXXX对这块内存下了个读断点,几次断下之后终于找到了罪魁祸首——一个函数内一个临时的指针变量delete掉了这块内存。

这不科学!这只是一个函数内的一个临时的指针变量,初始化为NULL,甚至逻辑都没有走到对它进行new赋值的地方,怎么会突然有了值,并且delete掉一个不相干的对象?!伪代码如下:

if(!DoSomething()) // 这里返回的是FALSE, 因此没走到new对pData赋值.
{
goto Exit;
}
BYTE* pData = NULL;

pData = new BYTE[1024];

Exit:
if(pData != NULL)
{
delete [] pData;
pData = NULL;
}

但是事实如此,反复review这段代码发现最有可能出现问题的地方在这处goto。通过编写demo发现VS 2005对于goto后面才定义的变量只会在函数进入前分配栈空间,要在执行到goto后面的赋值语句时才会对变量进行赋值。这也就让delete [] pData却释放了别处申请的内存成为了可能,因为指不定pData的栈内容是什么呢。

注意应尽量避免用goto,如果一定要使用保证函数进入就定义所有的变量并赋初值。

又一个 WordPress 站点

又一个 WordPress 站点。安装完WP这行字显示在首页。对于我来说,是又建了一个WP站点。

这些年来对web的兴趣依然不减,却也不再有研究。好多次,想通过web改变下互联网,更想满足一下我的创业梦,可苦于程序员局限的视野和想法,最终没有实践。好的点子是一方面,另一方面是我对web技术的欠缺。

其实,早在高中时期就接触了web技术,但由于没找到学习的途径,最终也只是停留在HTML写静态页面却搞不懂Form怎么用来做登录的层面。大学折腾过PHP,也捣鼓出一些站点,却没完全学会div+css,直到现在做了些界面开发才彻底理清margin和padding。总之在web上真是失败。

虽然如此,但这些年来对web的兴趣依然不减,建了一个又一个WP站点用来记录一些程序员历程,这个站点也不例外。之所以又建一个,是因为个人有点洁癖,喜欢整理,这里便是整理过后的存档。