日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

堆栈错误

發布時間:2025/5/22 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 堆栈错误 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

寫此文的目的是為了說明:
-> 并非所有的異常都能夠做到“不彈框優雅地退出”,堆棧錯誤因為可能影響安全,所以在異常處理時被加以了限制;
-> 堆、棧的頭部、尾部被破壞,共有4種情況,現象其實是不一樣的,應當加以區分。知道這一點應該能夠為排查錯誤帶來一些幫助。

  • 先來一個“普通的”異常:除零異常
  • #include <string.h> #include <stdio.h> #include <excpt.h> #include <stdlib.h>int main() {int a = 1;int b = 0;int ab = a / b;return 0; }

    ==========
    2. 除零異常是可以被正常捕獲并處理的

    #include <string.h> #include <stdio.h> #include <excpt.h> #include <stdlib.h>int MyMain() {int a = 1;int b = 0;printf("-----start-----\n");int ab = a / b;printf("-----finish-----\n");return 0; }int main() {__try{MyMain();}__except (EXCEPTION_EXECUTE_HANDLER){printf("!!!!! Quit with Exception In MyMain !!!!!\n");exit(-1);} }

    ==========
    3.堆頭部被破壞

    #include <string.h> #include <stdio.h> #include <excpt.h> #include <stdlib.h>int MyMain() {char *c = new char[5];c[0] = 'a';c[1] = 'b';c[2] = 'c';c[3] = 'd';c[4] = '\0';c[-1] = 'z';printf("c=%s\n", c);printf("-----start-----\n");delete c;printf("-----finish-----\n");return 0; }int main() {__try{MyMain();}__except (EXCEPTION_EXECUTE_HANDLER){printf("!!!!! Quit with Exception In MyMain !!!!!\n");exit(-1);} }


    注意以下幾點:
    (1) 紅色框部分:wrote to memory before start of heap buffer。
    (2) 堆錯誤即使加了異常處理語句,也會彈出錯誤框。
    (3) 當堆頭部被修改后,仍可以正常讀取堆內容。
    (4) 在釋放資源時才會發生異常。
    (5) 如果點擊“中止”,則程序隨即停止;如果點擊“重試”,則進入異常處理程序(說明其實還是能捕獲到的,只是無法直接隱藏錯誤窗口);如果點擊忽略,則程序繼續進行。下圖依次顯示了點擊“中止”“重試”“忽略”的情況。

    ==========
    4. 堆尾部被破壞

    #include <string.h> #include <stdio.h> #include <excpt.h> #include <stdlib.h>int MyMain() {char *c = new char[5];c[0] = 'a';c[1] = 'b';c[2] = 'c';c[3] = 'd';c[4] = '\0';c[5] = 'z';printf("c=%s\n", c);printf("-----start-----\n");delete c;printf("-----finish-----\n");return 0; }int main() {__try{MyMain();}__except (EXCEPTION_EXECUTE_HANDLER){printf("!!!!! Quit with Exception In MyMain !!!!!\n");exit(-1);} }


    注意以下幾點:
    (1) 紅色框部分:wrote to memory after end of heap buffer。
    其他同堆頭部被破壞的信息。

    ==========
    5. 棧頭部被破壞

    #include <string.h> #include <stdio.h> #include <excpt.h> #include <stdlib.h>int MyMain() {char c[5];memset(c, 0, sizeof(c));c[0] = 'a';c[1] = 'b';c[2] = 'c';c[3] = 'd';c[4] = '\0';c[-1] = 'z';printf("c=%s\n", c);printf("-----start-----\n");delete c;printf("-----finish-----\n");return 0; }int main() {__try{MyMain();}__except (EXCEPTION_EXECUTE_HANDLER){printf("!!!!! Quit with Exception In MyMain !!!!!\n");exit(-1);} }


    注意以下幾點:
    (1) 棧錯誤即使加了異常處理語句,也會彈出錯誤框。
    (2) 當棧頭部被修改后,仍可以正常讀取堆內容。
    (3) 在釋放資源時才會發生異常。
    (4) 如果點擊“中止”,則程序隨即停止;如果點擊“重試”,則進入異常處理程序(說明其實還是能捕獲到的,只是無法直接隱藏錯誤窗口);如果點擊忽略,則程序繼續進行,仍會繼續拋出異常,再次點擊忽略,再次拋出異常,第三次點擊繼續,程序進入異常處理。下圖依次顯示了點擊“中止”“重試”“忽略”的情況。

    ==========
    6.棧尾部被破壞

    #include <string.h> #include <stdio.h> #include <excpt.h> #include <stdlib.h>int MyMain() {char c[5];memset(c, 0, sizeof(c));c[0] = 'a';c[1] = 'b';c[2] = 'c';c[3] = 'd';c[4] = '\0';c[5] = 'z';printf("c=%s\n", c);printf("-----start-----\n");delete c;printf("-----finish-----\n");return 0; }int main() {__try{MyMain();}__except (EXCEPTION_EXECUTE_HANDLER){printf("!!!!! Quit with Exception In MyMain !!!!!\n");exit(-1);} }


    注意以下幾點:
    (1) 點擊兩次忽略后,程序結束。與棧頭部錯誤有所區別。(可能因為頭部指針沒有問題,所以沒有報“_CrtIsValidHeapPointer(pUserData)”異常)

    關于異常無法捕獲的補充材料請參考:
    Error的博文
    Error的博文

    總結

    以上是生活随笔為你收集整理的堆栈错误的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。