• <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ù)__歡迎移步我的獨(dú)立博客 codemaro.com 微博 kevinlynx

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

            很早前就想寫(xiě)點(diǎn)總結(jié)將編程中遇到的各種錯(cuò)誤刨根挖底地羅列出來(lái)。但是因?yàn)檫@些錯(cuò)誤(VC中開(kāi)調(diào)試器遇到的各種錯(cuò)誤對(duì)話框)都是隨機(jī)性的,真正想總結(jié)的時(shí)候又不想不起來(lái)有哪些錯(cuò)誤。恰好最近運(yùn)氣比較背,各種錯(cuò)誤都被我遇遍了,于是恰好有機(jī)會(huì)做個(gè)總結(jié)。

            這里所說(shuō)的VC下的錯(cuò)誤對(duì)話框時(shí)指在VC中開(kāi)調(diào)試器運(yùn)行程序時(shí),IDE彈出的對(duì)話框。

            1.不是錯(cuò)誤的錯(cuò)誤:斷言 .

            將斷言視為錯(cuò)誤其實(shí)有點(diǎn)可笑,但是因?yàn)橛行┩瑢W(xué)甚至不知道這個(gè),所以我稍微提一下。斷言對(duì)話框大致上類似于:

            assert

            斷言對(duì)話框是由assert引起的,在對(duì)話框上通常會(huì)給出表達(dá)式,例如assert( 0 ); 彈出對(duì)話框時(shí)就會(huì)將0這個(gè)表達(dá)式顯示出來(lái)(Expression:0)。關(guān)于assert的具體信息建議自己google。這里稍微提一下一個(gè)技巧:有時(shí)候?yàn)榱俗宎ssert提供更多的信息,我們可以這樣寫(xiě)一個(gè)assert:

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

            因?yàn)樽址挥迷诓紶柋磉_(dá)式中時(shí),始終為true,不會(huì)妨礙對(duì)expression的判斷,當(dāng)斷言發(fā)生時(shí)(expression為false) 時(shí),斷言對(duì)話框上就會(huì)顯示這個(gè)字符串,從而方便我們調(diào)試。

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

             

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

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

            wrongaccess

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

            char *p = 0;

            *p = 'a';

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

             

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

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

            char str[3];

            strcpy( str, "abc" );

            就將看到如下的對(duì)話框:

            stackerror 

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

             

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

            char *str = new char [2];

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

            delete [] str;//但是到這里時(shí)就肯定會(huì)崩潰

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

            heaperror

            似乎不同的DAMAGE對(duì)應(yīng)的錯(cuò)誤號(hào)(這里是47)都不一樣,因?yàn)檫@里的錯(cuò)誤發(fā)生在delete,而delete跟new很可能在不同的地方,所以這個(gè)錯(cuò)誤調(diào)試起來(lái)不是那么容易,很多時(shí)候只能靠經(jīng)驗(yàn)。

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

             

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

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

            run_functioncall2

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

            調(diào)用約定是指調(diào)用一個(gè)函數(shù)時(shí),函數(shù)參數(shù)的壓入順序、誰(shuí)來(lái)清理?xiàng)5膬?nèi)容等。例如默認(rèn)的C、C++調(diào)用約定__cdecl,對(duì)于函數(shù)的參數(shù)是從右往左壓入。而__stdcall(WIN API的調(diào)用約定)則是從左向右壓。我這里所說(shuō)的函數(shù)類型不一樣,就是指一個(gè)函數(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;

            }
             

             

            因?yàn)镕unc默認(rèn)地被處理為_(kāi)_cdecl,而show是__stdcall的,所以當(dāng)通過(guò)函數(shù)指針my_func時(shí),就導(dǎo)致了以上對(duì)話框的出現(xiàn)。但是當(dāng)p指向show2時(shí),又不會(huì)出錯(cuò),這是因?yàn)閟how2沒(méi)有參數(shù),不同的調(diào)用約定不影響這個(gè)規(guī)則。

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

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

             

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

             

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

             

            而如果不開(kāi)調(diào)試器,則會(huì)得到:

             

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

             

            7.VC運(yùn)行時(shí)檢查-未初始化變量

            VC的調(diào)試器會(huì)對(duì)代碼進(jìn)行運(yùn)行時(shí)檢查,這可能會(huì)導(dǎo)致VC彈出對(duì)你看上去正確的代碼。這也許不是一個(gè)錯(cuò)誤。例如:

            int test_var;

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

            test_var沒(méi)有初始化就進(jìn)行if判斷,當(dāng)運(yùn)行以上代碼開(kāi)調(diào)試器時(shí),就會(huì)得到如下對(duì)話框:

            withoutinit

            8.破壞的堆

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

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

            當(dāng)執(zhí)行以上代碼時(shí),因?yàn)閜的值已經(jīng)改變,提交到free的指針值變化,VC就會(huì)給出以下錯(cuò)誤提示:

            bad_heap

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

            評(píng)論

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

            很好,不過(guò)好多都沒(méi)有遇到過(guò)  回復(fù)  更多評(píng)論   

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

            全遭遇過(guò)了
            不錯(cuò)的總結(jié)  回復(fù)  更多評(píng)論   

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

            chao hao !

            高手一個(gè)啊!  回復(fù)  更多評(píng)論   

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

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

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

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

            @yafare
            例如?舉個(gè)例子代碼看看?(從對(duì)話框給的內(nèi)容來(lái)看,似乎就是因?yàn)楹瘮?shù)調(diào)用錯(cuò)誤)  回復(fù)  更多評(píng)論   

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

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

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

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

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

            頂  回復(fù)  更多評(píng)論   

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

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

            国产精品伊人久久伊人电影| 欧美亚洲国产精品久久蜜芽| 色综合久久无码中文字幕| 国产精品伊人久久伊人电影| 日日狠狠久久偷偷色综合96蜜桃 | 久久久久国产精品熟女影院| 午夜精品久久久久久影视777| 久久99九九国产免费看小说| 久久亚洲国产精品123区| 国产99久久久久久免费看| 亚洲伊人久久成综合人影院 | 久久久久久a亚洲欧洲aⅴ| 免费精品久久久久久中文字幕| 亚洲va国产va天堂va久久| 91亚洲国产成人久久精品| 国产三级观看久久| 日韩久久久久久中文人妻 | 亚洲精品高清国产一线久久| 一本久久a久久精品综合夜夜| 久久免费看黄a级毛片| 久久精品人人做人人爽电影| 久久香蕉国产线看观看99| 少妇熟女久久综合网色欲| 国内精品伊人久久久久网站| 欧美色综合久久久久久| 欧美精品一区二区精品久久| 亚洲AV无码一区东京热久久| 欧美日韩中文字幕久久久不卡| 77777亚洲午夜久久多喷| 国产91久久综合| 2020久久精品国产免费| 午夜人妻久久久久久久久| 国产香蕉久久精品综合网| 久久久久无码国产精品不卡| 亚洲第一极品精品无码久久| 久久福利资源国产精品999| 国产亚洲色婷婷久久99精品91| 国产精品久久久久9999高清| 亚洲AV日韩精品久久久久久| 久久久久久国产精品无码下载| 久久久久无码精品|