【記錄一次 Debug】圓括號位置放錯導致的 bug

碼字不易试伙,對你有幫助 點贊/轉(zhuǎn)發(fā)/關注 支持一下作者
微信搜公眾號:不會編程的程序圓
看更多干貨,獲取第一時間更新

推薦閱讀原文:
https://mp.weixin.qq.com/s/c5jot1YJcyeIniFkTVdNag

請看下面的程序四啰,它用來進行復制文件的操作雄可,你覺得它有問題嗎:

#include<stdio.h>
#include<stdlib.h>

int main(int argc, char* argv[]) {

    FILE* src_fp, * dest_fp;
    int ch;

    if (argc != 3) {
        fprintf(stderr, "usage: fcopy source dest\n");
        exit(EXIT_FAILURE);
    }

    if ((src_fp = fopen(argv[1], "rb") == NULL)) {
        fprintf(stderr, "Can't open file %s\n", argv[1]);
        exit(EXIT_FAILURE);
    }

    if ((dest_fp = fopen(argv[2], "wb")) == NULL) {
        fprintf(stderr, "Can't open file %s\n", argv[2]);
        fclose(src_fp);
        exit(EXIT_FAILURE);
    }

    while ((ch = getc(src_fp)) != EOF)
        putc(ch, dest_fp);

    fclose(src_fp);
    fclose(dest_fp);

    return 0;
}

程序可以正常編譯乌助,但是當我們在命令行中輸入正確的命令(命令格式:可執(zhí)行程序名 文件1 文件2)想要復制文件時呻率,會出現(xiàn)一個 assertion :

image

遇到這種問題我們不要慌張。我們先閱讀一下這個錯誤提示锄弱,看能否找到可以幫助自己 debug 的有用信息考蕾。

第一次看這個錯誤提示我是摸不著頭腦的。我仔細的檢查了自己的程序会宪,在確定“沒有問題”后肖卧,我又仔細的看了看這個錯誤提示。請大家注意 fgetc.cpp 這里掸鹅,這說明出錯的地方有可能是 fgetc 函數(shù)內(nèi)部塞帐。

注意接下來的一行:Expression: stream.valid();

到目前為止巍沙,我們知道可能是是程序執(zhí)行到 fgetc 函數(shù)內(nèi)部中 stream.valid() 這一行時產(chǎn)生了錯誤壁榕。那么問題到底是什么呢?

第一種辦法是 google 一下赎瞎,看看有沒有類似的問題解答;如果沒有颊咬,那么你就要靠自己了务甥。

我們思考一下,表達式 stream.valid() 什么情況下會出錯喳篇?有人可能要說了敞临,我連這個表達式的意思是什么都不知道,我怎么知道什么情況下會出錯呢麸澜?其實我也不知道挺尿,但這不影響我們思考出錯的可能性。

最直觀的一種可能就是 stream 是空指針時,對其進行成員訪問”喾現(xiàn)在我們需要做的就是找到自己程序中哪里可能傳入了空指針熟史。

這也很簡單,程序中我們只有一個函數(shù)和 fgetc 有關 —— getc 窄俏。但為什么我們用的是 getc 但是出錯的是 fgetc 呢蹂匹?因為 getc 函數(shù)的實現(xiàn)依賴于 fgetc 函數(shù)。

我們來看一下我們對 getc 的調(diào)用:

getc(src_fp)

這時你可能又要說了凹蜈,src_fp 我們不是做過空指針檢查嗎限寞,為什么還會出錯?不要著急著下結(jié)論仰坦,我們來看看這個檢查 src_fp 的語句:

    if ((src_fp = fopen(argv[1], "rb") == NULL)) {
        ...
    }

其實到這一步履植,明眼人都能看出問題的所在了。

當我確定了 src_fp 可能為空指針時悄晃,又看到了 if 語句中的 = 和 == 玫霎,我已經(jīng)明白錯誤所在了。讀過《C 陷阱和缺陷》的朋友都清楚传泊,這是一個經(jīng)典的由優(yōu)先級引發(fā)的錯誤:

因為 C 語言中鼠渺,賦值運算的優(yōu)先級往往是比大多數(shù)其他運算符都要低的(包括關系運算符 == 和 != ),if 語句的判斷會被編譯器理解為:

if ( (src_fp =  (fopen(argv[1], "rb") == NULL) ) {
        ...
    }

我們知道:fopen(argv[1], "rb") == NULL的值的可能只有兩個:0 或 1眷细,不管我們將哪個賦值給 src_fp 拦盹,都會引發(fā)問題。

雖然最終的錯誤嚴謹?shù)恼f并不能說是空指針異常溪椎,但是我們發(fā)現(xiàn)了形參 stream 是有問題的普舆,也就說明我們傳入的實參是不正確的。

引發(fā)這個問題的原因是這樣的:在我寫這個 if 語句的判斷表達式時校读,我在 if 后打了一次左括號沼侣,VS 為我補了一個右括號(這樣就完整的錄入了())。然后在括號內(nèi)我先寫了 src_fp = fopen(argv[1], "rb")歉秫。在要寫出判等語句前蛾洛,我認為應該為前面的賦值語句添加括號,所以我將光標移動到了 src_fp 前雁芙,打出了左括號(轧膘,然后又我將光標移動到 fopen 函數(shù)的調(diào)用后,敲了一次左括號兔甘,很可惜谎碍,VS 就是這么坑爹,由于右邊已經(jīng)有了一個右括號(這是屬于整體的)洞焙,我白敲了一次右括號蟆淀,并沒有錄入這個右括號拯啦。后面在寫出判等代碼后(if ((src_fp = fopen(argv[1], "rb") == NULL)),VS 其實是有報錯的熔任,但我自以為是的只是簡單的在后面添加了一個右括號而已褒链。從而造成了這個 bug 。

因為一個不經(jīng)大腦的右括號笋敞,我花了很久 debug 碱蒙,又“浪費”時間寫了一篇博客!這個故事告訴我們夯巷,下次在你添加右括號時赛惩,一定要停下了思考一下,以避免寫一篇“不必要”的博客趁餐。

雖然這個 bug 其實并不難找喷兼,但是我依然明白了,即使面對可能再難的 bug后雷,稍加思考季惯,它可能就會變成“紙老虎”。

或者臀突,讓你自己不要寫出這樣的 bug 勉抓。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市候学,隨后出現(xiàn)的幾起案子藕筋,更是在濱河造成了極大的恐慌,老刑警劉巖梳码,帶你破解...
    沈念sama閱讀 221,331評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件隐圾,死亡現(xiàn)場離奇詭異,居然都是意外死亡掰茶,警方通過查閱死者的電腦和手機暇藏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,372評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來濒蒋,“玉大人盐碱,你說我怎么就攤上這事』铮” “怎么了瓮顽?”我有些...
    開封第一講書人閱讀 167,755評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長焰坪。 經(jīng)常有香客問我,道長聘惦,這世上最難降的妖魔是什么某饰? 我笑而不...
    開封第一講書人閱讀 59,528評論 1 296
  • 正文 為了忘掉前任儒恋,我火速辦了婚禮,結(jié)果婚禮上黔漂,老公的妹妹穿的比我還像新娘诫尽。我一直安慰自己,他們只是感情好炬守,可當我...
    茶點故事閱讀 68,526評論 6 397
  • 文/花漫 我一把揭開白布牧嫉。 她就那樣靜靜地躺著,像睡著了一般减途。 火紅的嫁衣襯著肌膚如雪酣藻。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,166評論 1 308
  • 那天鳍置,我揣著相機與錄音辽剧,去河邊找鬼。 笑死税产,一個胖子當著我的面吹牛怕轿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播辟拷,決...
    沈念sama閱讀 40,768評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼撞羽,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了衫冻?” 一聲冷哼從身側(cè)響起诀紊,我...
    開封第一講書人閱讀 39,664評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎羽杰,沒想到半個月后渡紫,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,205評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡考赛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,290評論 3 340
  • 正文 我和宋清朗相戀三年惕澎,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片颜骤。...
    茶點故事閱讀 40,435評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡唧喉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出忍抽,到底是詐尸還是另有隱情八孝,我是刑警寧澤,帶...
    沈念sama閱讀 36,126評論 5 349
  • 正文 年R本政府宣布鸠项,位于F島的核電站干跛,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏祟绊。R本人自食惡果不足惜楼入,卻給世界環(huán)境...
    茶點故事閱讀 41,804評論 3 333
  • 文/蒙蒙 一哥捕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧嘉熊,春花似錦遥赚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,276評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至孕惜,卻和暖如春愧薛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背诊赊。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工厚满, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人碧磅。 一個月前我還...
    沈念sama閱讀 48,818評論 3 376
  • 正文 我出身青樓碘箍,卻偏偏與公主長得像,于是被迫代替她去往敵國和親鲸郊。 傳聞我的和親對象是個殘疾皇子丰榴,可洞房花燭夜當晚...
    茶點故事閱讀 45,442評論 2 359