亚洲免费乱码视频,日韩 欧美 国产 动漫 一区,97在线观看免费视频播国产,中文字幕亚洲图片

      1. <legend id="ppnor"></legend>

      2. 
        
        <sup id="ppnor"><input id="ppnor"></input></sup>
        <s id="ppnor"></s>

        C語言難點(diǎn)揭秘[3]

        字號:

        懸空指針
            懸空指針比較棘手。當(dāng)程序員在內(nèi)存資源釋放后使用資源時會發(fā)生懸空指針(請參見清單 5):
            清單 5. 懸空指針
             void f8()
             {
             struct x *xp;
             xp = (struct x *) malloc(sizeof (struct x));
             xp.q = 13;
             ...
             free(xp);
             ...
             /* Problem! There's no guarantee that
             the memory block to which xp points
             hasn't been overwritten. */
             return xp.q;
             }
            傳統(tǒng)的“調(diào)試”難以隔離懸空指針。由于下面兩個明顯原因,它們很難再現(xiàn):
            即使影響提前釋放內(nèi)存范圍的代碼已本地化,內(nèi)存的使用仍然可能取決于應(yīng)用程序甚至(在極端情況下)不同進(jìn)程中的其他執(zhí)行位置。
            懸空指針可能發(fā)生在以微妙方式使用內(nèi)存的代碼中。結(jié)果是,即使內(nèi)存在釋放后立即被覆蓋,并且新指向的值不同于預(yù)期值,也很難識別出新值是錯誤值。
            懸空指針不斷威脅著 C 或 C++ 程序的運(yùn)行狀態(tài)。
            數(shù)組邊界違規(guī)
            數(shù)組邊界違規(guī)十分危險,它是內(nèi)存錯誤管理的最后一個主要類別。回頭看一下清單 1;如果 explanation 的長度超過 80,則會發(fā)生什么情況?回答:難以預(yù)料,但是它可能與良好情形相差甚遠(yuǎn)。特別是,C 復(fù)制一個字符串,該字符串不適于為它分配的 100 個字符。在任何常規(guī)實(shí)現(xiàn)中,“超過的”字符會覆蓋內(nèi)存中的其他數(shù)據(jù)。內(nèi)存中數(shù)據(jù)分配的布局非常復(fù)雜并且難以再現(xiàn),所以任何癥狀都不可能追溯到源代碼級別的具體錯誤。這些錯誤通常會導(dǎo)致數(shù)百萬美元的損失。
            內(nèi)存編程的策略
            勤奮和自律可以讓這些錯誤造成的影響降至最低限度。下面我們介紹一下您可以采用的幾個特定步驟;我在各種組織中處理它們的經(jīng)驗是,至少可以按一定的數(shù)量級持續(xù)減少內(nèi)存錯誤。
            編碼風(fēng)格
            編碼風(fēng)格是最重要的,我還從沒有看到過其他任何作者對此加以強(qiáng)調(diào)。影響資源(特別是內(nèi)存)的函數(shù)和方法需要顯式地解釋本身。下面是有關(guān)標(biāo)頭、注釋或名稱的一些示例(請參見清單 6)。
            清單 6. 識別資源的源代碼示例
             /********
             * ...
             *
             * Note that any function invoking protected_file_read()
             * assumes responsibility eventually to fclose() its
             * return value, UNLESS that value is NULL.
             *
             ********/
             FILE *protected_file_read(char *filename)
             {
             FILE *fp;
             fp = fopen(filename, "r");
             if (fp) {
             ...
             } else {
             ...
             }
             return fp;
             }
             /*******
             * ...
             *
             * Note that the return value of get_message points to a
             * fixed memory location. Do NOT free() it; remember to
             * make a copy if it must be retained ...
             *
             ********/
             char *get_message()
             {
             static char this_buffer[400];
             ...
             (void) sprintf(this_buffer, ...);
             return this_buffer;
             }
             /********
             * ...
             * While this function uses heap memory, and so
             * temporarily might expand the over-all memory
             * footprint, it properly cleans up after itself.
             *
             ********/
             int f6(char *item1)
             {
             my_class c1;
             int result;
             ...
             c1 = new my_class(item1);
             ...
             result = c1.x;
             delete c1;
             return result;
             }
             /********
             * ...
             * Note that f8() is documented to return a value