抓虫记(二)可变参数和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:

  如果拿去做笔试或者面试题,估计会害死一堆...

 
posted @ 2012-10-15 15:29  赤脚的懒虫  阅读(1857)  评论(6编辑  收藏  举报