抓蟲記(二)可變參數和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:

  如果拿去做筆試或者面試題,估計會害死一堆...

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM