C 異常處理的深入理解

2022-08-18 01:24:08 字數 2927 閱讀 7179

1,問題:

1,如果在 main 函式中丟擲異常會發生什麼?

1,不處理,則崩潰;

2,如果異常不處理,最後會傳到**?

3,下面的**輸出什麼?

4,異常的最終處理程式設計實驗:

1 #include 2

3using

namespace

std;45

class

test 613

14 ~test()

1519

};20

21int

main()

22

1,有了線索,main() 函式中丟擲的異常也許會被乙個最終的函式處理;

5,異常無法被處理的情況:

1,如果異常無法被處理,terminate() 結束函式會被自動呼叫;

2,預設情況下,terminate() 呼叫庫函式 abort() 終止程式;

1,三款編譯器在 terminate() 函式內部實現上面有點兒差異;

2,比如列印字串提示當前程式出來異常,彈出對話方塊告訴使用者當前應程式要異常終止(實際還沒終止);

3,abort() 函式使得程式執行異常而立即退出;

4,c++ 支援替換預設的 terminate() 函式實現;

1,c++ 可以自定義結束函式,自定義最終處理異常的函式來替換預定義的 terminate();

6,terminate() 函式的替換:

1,自定義乙個無返回值無引數的函式;

1,不能丟擲任何異常;

1,最後處理異常的函式了,所以不能丟擲任何異常;

2,必須以某種方式結束當前程式;

1,沒有做到這一點兒,程式出現什麼樣的行為就不得而知了,當然 windows 和 linux 系統會將這個程式自動終止;

2,呼叫 set_terminate() 設定自定義的結束函式;

1,引數型別為 void(*)();

1,函式指標,沒有引數、沒有返回值;

2,返回值為預設的 terminate() 函式入口位址;

7,自定義結束函式程式設計實驗:

1 #include 2 #include 3 #include //

c++ 標準庫中與異常相關的標頭檔案;45

using

namespace

std;67

void

my_terminate()813

14class

test

1522

23 ~test()

2428

};29

30int

main()

31

1,列印結果:

1,exit(1) 的時候:

test()

void my terminate()

~test()

2,abort() 的時候:

test()

void my terminate()

已放棄2,在 main() 函式中扔出的異常如果沒有被處理,會被最終的乙個全域性結束函式處理掉;

3,c++ 編譯器之間存在差異;

8,問題:

1,如果析構函式中丟擲異常會發生什麼情況?

1,前面說有可能導致資源無法釋放,記憶體洩漏等;

2,這裡有兩點:

1,析構函式是釋放資源的地方,如果丟擲異常,有可能導致資源無法正確的釋放;

2,在析構函式中丟擲異常有可能導致全域性的結束函式 terminate() 被重複的呼叫,這是很可怕的,有可能讓我們的系統進入乙個不穩定的狀態;

2,析構函式丟擲異常程式設計實驗:

1 #include 2 #include 3 #include 4

5using

namespace

std;67

void

my_terminate()813

14class

test

1522

23 ~test()

2430

};31

32int

main()

33

1,列印結果:

1,test()

void my terminate()  // main() 中 throw 1 丟擲異常後第一次執行 my_terminate() 函式的結果;

~test()  // 呼叫 exit(),執行析構函式;

void my terminate()  // 在執行析構函式的時候,再次扔出異常 throw 2,第二次執行 my_terminate() 函式;

2,my_terminate() 函式:

1,作為最後乙個被呼叫的異常處理函式,任務是很重的;

2,要負責進行應用程式級別的資源釋放;

3,第一次呼叫的時候,所有的資源已經被釋放完了,第二次呼叫就類似對堆空間的記憶體第二次釋放,造成應用程式的不穩定,因為這裡 linux 系統非常穩定,會幫我們處理好連續釋放資源的問題;

4,如果進行嵌入式開發,作業系統就不見得有這樣的能力對每乙個系統做這樣的監控,產生的行為使未定義的;

5,這也解釋了 c++ 預設呼叫的是 abort() 而不是 exit(1),因為 abort() 直接的強制結束當前的應用程式,不會呼叫析構函式,就是拍析構函式中扔出異常;

9,小結:

1,如果異常沒有被處理,最後 terminate() 結束整個程式;

2,terminate() 是整個程式釋放系統資源的最後機會;

3,結束函式可以自定義,但不能繼續丟擲異常;

4,析構函式中不能丟擲異常,可能導致 terminate() 多次呼叫;

深入理解C語言 深入理解指標

關於指標,其是c語言的重點,c語言學的好壞,其實就是指標學的好壞。其實指標並不複雜,學習指標,要正確的理解指標。指標也是一種變數,占有記憶體空間,用來儲存記憶體位址 指標就是告訴編譯器,開闢4個位元組的儲存空間 32位系統 無論是幾級指標都是一樣的 p操作記憶體 在指標宣告時,號表示所宣告的變數為指...

深入理解C語言 深入理解指標

關於指標,其是c語言的重點,c語言學的好壞,其實就是指標學的好壞。其實指標並不複雜,學習指標,要正確的理解指標。指標也是一種變數,占有記憶體空間,用來儲存記憶體位址 指標就是告訴編譯器,開闢4個位元組的儲存空間 32位系統 無論是幾級指標都是一樣的 p操作記憶體 在指標宣告時,號表示所宣告的變數為指...

Linux深入理解Socket異常

在各種網路異常情況的背後,tcp是怎麼處理的?又是怎樣把處理結果反饋給上層應用的?本文就來討論這個問題。分為兩個場景來討論 建立連線時的異常情況 1 正常情況下 經過三次握手,客戶端連線成功,服務端有乙個新連線到來。2 客戶端連線了服務端未監聽的埠 在這種情況下,服務端會對收到的syn回應乙個rst...