抓虫记(二)可变参数和std::string的故事
前段时间,碰到一个bug,很奇怪的bug:
1. 这个bug在win7中,普通权限下运行release版本,会崩溃。抓取dump,分析也找不到具体在哪行代码出问题。但是如果以管理员身份运行的话,就一点事情都没有。
2. 在debug状态下,调试代码,一点问题都没有。
是操作系统的问题?因为用户权限不够?我们没有做什么特殊的操作啊?为什么一定要管理员权限呢?在有些电脑还不会出现这个bug...
这个时候,没办法我只能采用最笨的办法:printf。隔一个地方就打印一条日志,最后定位到以下代码,出现问题:
string sSQLUser="test", sSQLPass; char msgBuffer[256] = {0}; if(!sSQLUser.empty()) sprintf(msgBuffer, ", SQLUser:%s", sSQLUser); else sprintf(msgBuffer, ", SQLUser:"); //...
猛的一看,发现不了什么问题啊???写了见到的例子,用vs跑了下,确实会出现问题。特别在linux下跑这种例子,不管是release还是debu都直接挂掉...
只好好好找找为什么...发现似乎是可变参数和string一起使用的时候出现问题。好好研究了下可变参数的原理,原来是可变参数中,强制把string对象转为char*,并不会自动把string自动转为char*的字符串。这样格式化的时候,sprintf取的并不是实质的内容(test),而是对象的首地址,只不过是被强转为了char*格式。
这个bug很好修复:
string sSQLUser="test", sSQLPass; char msgBuffer[256] = {0}; if(!sSQLUser.empty()) sprintf(msgBuffer, ", SQLUser:%s", sSQLUser.c_str()); else sprintf(msgBuffer, ", SQLUser:"); //...
哎~~~为什么会犯这个错误呢?
1. 不要相信编译器,不要认为什么事情都有别人帮你做好,其实,有时候我们手动的告诉编译器会更好。
2. 对C/C++的一些特性,一定要深刻的理解。
PS:
如果拿去做笔试或者面试题,估计会害死一堆...