前段時間,碰到一個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:
如果拿去做筆試或者面試題,估計會害死一堆...