• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            loop_in_codes

            低調(diào)做技術(shù)__歡迎移步我的獨立博客 codemaro.com 微博 kevinlynx

            調(diào)試經(jīng)驗總結(jié)-VC下的錯誤對話框(陸續(xù)更新6.12.2008)

            很早前就想寫點總結(jié)將編程中遇到的各種錯誤刨根挖底地羅列出來。但是因為這些錯誤(VC中開調(diào)試器遇到的各種錯誤對話框)都是隨機性的,真正想總結(jié)的時候又不想不起來有哪些錯誤。恰好最近運氣比較背,各種錯誤都被我遇遍了,于是恰好有機會做個總結(jié)。

            這里所說的VC下的錯誤對話框時指在VC中開調(diào)試器運行程序時,IDE彈出的對話框。

            1.不是錯誤的錯誤:斷言 .

            將斷言視為錯誤其實有點可笑,但是因為有些同學(xué)甚至不知道這個,所以我稍微提一下。斷言對話框大致上類似于:

            assert

            斷言對話框是由assert引起的,在對話框上通常會給出表達式,例如assert( 0 ); 彈出對話框時就會將0這個表達式顯示出來(Expression:0)。關(guān)于assert的具體信息建議自己google。這里稍微提一下一個技巧:有時候為了讓assert提供更多的信息,我們可以這樣寫一個assert:

            assert( expression && "Function : invalid argument!" );

            因為字符串被用在布爾表達式中時,始終為true,不會妨礙對expression的判斷,當(dāng)斷言發(fā)生時(expression為false) 時,斷言對話框上就會顯示這個字符串,從而方便我們調(diào)試。

            要解決這個問題,首先要確定斷言發(fā)生的位置,如果是你自己設(shè)置的斷言被引發(fā),就很好解決,如果是系統(tǒng)內(nèi)部的函數(shù)產(chǎn)生的,那么一般是因為你傳入的函數(shù)參數(shù)無效引起。

             

            2.內(nèi)存相關(guān):最簡單的非法訪問:

            C、C++程序中經(jīng)常誤用無效的指針,從而大致各種各樣的非法內(nèi)存訪問(寫/讀)。最簡單的情況類似于:

            wrongaccess

            這樣的情況由類似以下代碼引起:

            char *p = 0;

            *p = 'a';

            當(dāng)你看到類似于“寫入位置XXXX時發(fā)生訪問沖突“時,那么你大致可以斷定,你的程序在某個地方訪問到非法內(nèi)存。開調(diào)試器對調(diào)用堆棧進行跟蹤即可找出錯誤。

             

            3.內(nèi)存相關(guān):不小心的棧上數(shù)組越界:

            當(dāng)你寫下類似以下的代碼時:

            char str[3];

            strcpy( str, "abc" );

            就將看到如下的對話框:

            stackerror 

            對話框大致的意思就是說str周圍的棧被破壞了,因為str本身就被放在棧上,所以strcpy(str,"abc")多寫入的'\0'就寫到非法的棧區(qū)域。看到這樣的對話框可以根據(jù)調(diào)用堆棧定位到錯誤發(fā)生的函數(shù),然后檢查此函數(shù)內(nèi)部定義的數(shù)組訪問,即可解決問題。

             

            4.內(nèi)存相關(guān):不小心的堆上數(shù)組越界:
            并不是每次數(shù)組越界都會得到上面所描述的錯誤,當(dāng)數(shù)組是在堆上分配時,情況就變得隱秘得多:

            char *str = new char [2];

            strcpy( str, "ab" ); //執(zhí)行到這里時并不見得會崩潰

            delete [] str;//但是到這里時就肯定會崩潰

            以上代碼導(dǎo)致的錯誤對話框還要詭異些:

            heaperror

            似乎不同的DAMAGE對應(yīng)的錯誤號(這里是47)都不一樣,因為這里的錯誤發(fā)生在delete,而delete跟new很可能在不同的地方,所以這個錯誤調(diào)試起來不是那么容易,很多時候只能靠經(jīng)驗。

            當(dāng)看到類似的對話框時,根據(jù)調(diào)用堆棧跟到delete時,你就可以大致懷疑堆上數(shù)組越界。

             

            5.調(diào)用相關(guān):函數(shù)調(diào)用約定帶來的錯誤:

            這是所有我這里描述的錯誤中最詭異的一種,先看下對話框大致的樣子:

            run_functioncall2

            對話框大致的意思就是說(沒開調(diào)試器時對話框樣式可能不一樣),通過函數(shù)指針調(diào)用某個函數(shù)時,函數(shù)指針的類型(函數(shù)原型)可能與函數(shù)指針指向的函數(shù)的類型不一樣。這里的類型不一致主要是調(diào)用約定(call conversation)不一樣。如果函數(shù)類型(參數(shù)個數(shù),返回值)不一樣,一般不會出錯。

            調(diào)用約定是指調(diào)用一個函數(shù)時,函數(shù)參數(shù)的壓入順序、誰來清理棧的內(nèi)容等。例如默認(rèn)的C、C++調(diào)用約定__cdecl,對于函數(shù)的參數(shù)是從右往左壓入。而__stdcall(WIN API的調(diào)用約定)則是從左向右壓。我這里所說的函數(shù)類型不一樣,就是指一個函數(shù)是使用__cdecl,還是__stdcall。例如以下代碼:

             

            #include <iostream> 

            void __stdcall show( const char *str )

            {

            }
             

            void __stdcall show2()

            {

            }
             

            int main()

            {

            typedef
            void (*Func)( const char *);

            void *p = show;

            Func my_func
            = (Func) p;

            my_func(
            "kevin" );

            return 0;

            }
             

             

            因為Func默認(rèn)地被處理為__cdecl,而show是__stdcall的,所以當(dāng)通過函數(shù)指針my_func時,就導(dǎo)致了以上對話框的出現(xiàn)。但是當(dāng)p指向show2時,又不會出錯,這是因為show2沒有參數(shù),不同的調(diào)用約定不影響這個規(guī)則。

            6.異常相關(guān):默認(rèn)終止程序

            當(dāng)我們使用C++庫時,因為庫本身可能會拋出C++異常,如果你不捕獲這個異常,那么C++默認(rèn)就會調(diào)用abort(或者exit)函數(shù)終止程序。例如:

             

            void test()
            {
               
            throw std::exception( "some exceptions" );
            }

             

            當(dāng)你調(diào)用test函數(shù)時,如果不catch這個異常,開調(diào)試器就會得到類似的錯誤對話框:

             

            而如果不開調(diào)試器,則會得到:

             

            當(dāng)你看到類似于“This application has requested the Runtime to terminate it…”之類的字眼時,那就表明程序調(diào)用了abort(或exit)函數(shù),導(dǎo)致程序異常終止。其實這個錯誤只要開調(diào)試器,一般可以準(zhǔn)確定位錯誤的發(fā)生點。

             

            7.VC運行時檢查-未初始化變量

            VC的調(diào)試器會對代碼進行運行時檢查,這可能會導(dǎo)致VC彈出對你看上去正確的代碼。這也許不是一個錯誤。例如:

            int test_var;

            if( test_var == -1 )
            {
                test_var = 0;
            }

            test_var沒有初始化就進行if判斷,當(dāng)運行以上代碼開調(diào)試器時,就會得到如下對話框:

            withoutinit

            8.破壞的堆

            VC對于在堆上分配的內(nèi)存都做了記錄,我想這主要用于free釋放內(nèi)存時做歸還處理。

            char *p = (char*) malloc( 100 );
            p += 10;
            free( p );

            當(dāng)執(zhí)行以上代碼時,因為p的值已經(jīng)改變,提交到free的指針值變化,VC就會給出以下錯誤提示:

            bad_heap

            posted on 2008-04-24 13:43 Kevin Lynx 閱讀(8210) 評論(9)  編輯 收藏 引用 所屬分類: c/c++通用編程

            評論

            # re: 調(diào)試經(jīng)驗總結(jié)-VC下的錯誤對話框 2008-04-24 17:19 王曉軒

            很好,不過好多都沒有遇到過  回復(fù)  更多評論   

            # re: 調(diào)試經(jīng)驗總結(jié)-VC下的錯誤對話框 2008-04-24 18:28 mm

            全遭遇過了
            不錯的總結(jié)  回復(fù)  更多評論   

            # re: 調(diào)試經(jīng)驗總結(jié)-VC下的錯誤對話框 2008-04-25 11:38 夢在天涯

            chao hao !

            高手一個啊!  回復(fù)  更多評論   

            # re: 調(diào)試經(jīng)驗總結(jié)-VC下的錯誤對話框 2008-04-26 22:28 yafare

            調(diào)用相關(guān):函數(shù)調(diào)用約定帶來的錯誤

            不一定是調(diào)用約定錯誤,數(shù)組訪問越界覆蓋掉vc設(shè)置的cookie,也可能是這樣的提示  回復(fù)  更多評論   

            # re: 調(diào)試經(jīng)驗總結(jié)-VC下的錯誤對話框 2008-04-28 09:15 Kevin Lynx

            @yafare
            例如?舉個例子代碼看看?(從對話框給的內(nèi)容來看,似乎就是因為函數(shù)調(diào)用錯誤)  回復(fù)  更多評論   

            # re: 調(diào)試經(jīng)驗總結(jié)-VC下的錯誤對話框 2008-04-28 22:00 草上飛

            呵呵我剛才在Matlab中也出現(xiàn)了這樣的問題,想一想一小時前我還使用的好好的啊!仔細(xì)想想和操作系統(tǒng)相關(guān)的就是我把桌面主題給換了,隱約感覺到是這里的問題,于是我就把主題改為window XP,果然問題解決了,matlab可以正常啟動了!
              回復(fù)  更多評論   

            # re: 調(diào)試經(jīng)驗總結(jié)-VC下的錯誤對話框 2008-04-29 22:22 李錦俊

            這些都經(jīng)常遇到,還有一些很難遇到,更隱秘的錯誤才會導(dǎo)致的出錯對話框。  回復(fù)  更多評論   

            # re: 調(diào)試經(jīng)驗總結(jié)-VC下的錯誤對話框(陸續(xù)更新5.5.2008) 2008-05-09 08:59 joke

            頂  回復(fù)  更多評論   

            # re: 調(diào)試經(jīng)驗總結(jié)-VC下的錯誤對話框(陸續(xù)更新6.12.2008) 2008-07-04 07:30 路緣

            謝謝樓主分享,樓主真是有心人。  回復(fù)  更多評論   

            亚洲国产香蕉人人爽成AV片久久| 精品国产乱码久久久久软件| 久久婷婷成人综合色综合| 精品熟女少妇AV免费久久| 久久亚洲精品中文字幕| 久久精品国产精品青草| 亚洲伊人久久综合影院| 国产精品久久久久天天影视| 国产—久久香蕉国产线看观看| 久久综合九色欧美综合狠狠| 国内精品久久久久影院亚洲| 日本国产精品久久| 久久精品国产精品亚洲精品| 久久综合亚洲鲁鲁五月天| 欧美黑人激情性久久| 91精品国产91久久久久久蜜臀 | 久久人人爽人爽人人爽av| 无码国内精品久久人妻| 久久国产影院| 久久国产精品成人免费| 欧美亚洲色综久久精品国产| 国产精品狼人久久久久影院 | 久久国产精品-久久精品| 色婷婷噜噜久久国产精品12p| 久久男人Av资源网站无码软件| 久久九九久精品国产免费直播| 99久久无色码中文字幕| 精品综合久久久久久98| 久久成人小视频| 久久国产精品无| 午夜精品久久久久久影视777| 国内精品久久久久影院网站| 99久久综合狠狠综合久久| 久久这里只有精品18| 久久精品亚洲一区二区三区浴池 | 久久99精品久久久久久水蜜桃 | 青青草国产精品久久| 国产高潮国产高潮久久久| 久久精品aⅴ无码中文字字幕不卡 久久精品aⅴ无码中文字字幕重口 | 性欧美大战久久久久久久久| 伊人久久久AV老熟妇色|