析构函数与运行错误
??今天在做數據結構的實驗課作業時,突然一直運行錯誤,可我檢查了幾次代碼,也沒有發現哪里有錯(也并沒有經常導致運行錯誤的,數組越界那些),經過20min左右的試探和摸索,終于發現了這次運行錯誤的時間,并且,還和析構函數有些關系
?
?(而且,最尷尬的是,在我發現以后,我才想起來,這個錯誤在我學C++的時候就犯過了,當時我還在自己的代碼上注釋過這個錯誤,強調以后要注意)…
?
然而到學數據結構時,居然印象已經不太深刻了…故寫此博文,一方面,以后自己再犯這個錯,可以快速找到;另一方面,如果有人不幸踩到這個坑,也許他們能從這篇中有一二啟發。
?
? 題目:
我最初的代碼(DevC上正常運行,但在oj上報錯):
報錯頁面截圖:
? 百思不得其解,我就開始搜這些錯誤提示,然而搜了十幾分鐘,也一無所獲,他們提到的數組越界等問題,我也沒有,而對于ans列表,我也有給它的list數組動態分配足夠大的空間。我仔仔細細檢查了幾次,還是覺得自己找不到錯(此處對我當時的無知進行了美化,其實我當時是覺得,我應該沒錯吧,好像是oj錯了)
? 就在這時,突然想到了上學期學C++的類時,經常容易在析構函數上犯錯,于是屏蔽了析構函數,提交一次
? 發現屏蔽析構函數以后,居然就沒有運行錯了,可謂是又驚又喜....
? 接下來我仔細想了想,這兩種到底有什么區別,為什么沒有析構就能通過,這時我突然想起
? 因為我在 MergeList中,傳入的參數 a 和 b 都是按照值傳遞的方式傳遞的,既然為值傳遞,作為臨時變量,傳參時會自動調用構造函數,返回時,會自動調用參數的析構函數...(而析構函數,本來是不會清楚動態分配的空間的,但既然我重寫了析構,那new出來的數組空間,肯定都被析構掉了)
? 可是,有一個很嚴重的問題是,a 和 b 作為參數傳入時,它們的list數組,和主函數中的 temp1 和 temp2 的list數組,是共享空間的。而主函數與逆行完以后,temp1 和 temp2 必定也會調用析構函數,就相當于把同一個空間,析構了兩次,自然會有運行錯誤
? 那么,有沒有什么方法能避免這個錯誤呢?
??
? 當然是有的~
? 1. ?首先,如果不寫析構函數就行,就如我的上一張截圖,不自己寫,默認的析構函數,是不會析構動態分配的空間的,雖然這種做法,畢竟還是不合適,但它確實可以避免許多問題
? (BTW,在這里說一下,重寫析構函數以后,真的需要萬事小心,我現在突然想起來,當初學C++的類時,幾乎所有的錯誤,都是出現在析構函數上的,每次一屏蔽它就沒事,不然就一直有錯誤)
? 2. ?更加推薦的處理方法時,將 a 和 b 用引用的方式傳遞為參數,這樣a和b就不是臨時對象,函數也就不會在返回時,自動調用它們的析構函數了,就像這樣
? const只是避免自己不小心改了不該改的a和b,不加也行,關鍵是一定要加上引用
? 而且這個方法還有一個除了避免出錯之外的好處,就是...運行速度更快了,從8變成了0
? 從這個故事中,得到了一個教訓:
? 經常踩的坑,也還是應該好好記錄整理下來。想當初,踩了那么多次析構函數的坑,出了那么多次運行錯誤,我以為印象深刻到,隨時都能想起來的地步了。然而,今天還是找了很久才發現
? 因此,特開博客的“經驗教訓”分類,以記下我在編程上遇到的,比較特別,或者比較值得記錄下來的錯誤,并記下自己當時是怎么解決的。
轉載于:https://www.cnblogs.com/mofushaohua/p/7789415.html
總結
- 上一篇: 【BZOJ3866】The Romant
- 下一篇: 硬件能力与智能AI-Zoomla!逐浪C