程序運行中,最詭異的就是內存問題了。(限于個人經驗問題,暫時只碰到這個程度的,如果還有詭異程度更甚的,請告訴我)內存問題仿佛天外流星,不知其何時來,不知其癥狀如何,飄忽不定,直到程序崩潰為止。
今天就碰到了一例。
void fun()
{
vector<double> v1;
vector<double> v2;
process();
........
}
在某個函數體內,申明了v1,和v2兩個vector,然后balabala,直到要退出fun的作用域,析構v1的時候,程序崩潰。
嘗試著把v1,v2的申明順序換了一下,癥狀變了,在析構v2的時候出錯;接著嘗試,把v1,v2設為static變量,發現這會不報錯,但是出了fun函數之后,在其他函數體內又出現類似的問題。
至此,基本可以下結論了。這是一起典型的內存問題,可能是數組訪問越界,可能是內存泄露等等。
你想問,為什么可以下這個結論?我們可以來分析一下:
首先,并不是v1,或者v2的析構出錯;而是第一個申明的變量析構出問題。這給了你什么啟發?在函數體內申明的變量(非static,也不是用new申請的內存空間),都屬于局部變量,程序統一用棧來管理。申明的時候一個個push進棧,退出作用域的時候,一個個pop出棧,調用變量自身的析構函數。當pop到最后一個的時候出錯,說明棧已經被弄亂了,無法根據地址正確的調用該變量的析構函數。
為什么用static變量就不報錯呢,很簡單,static是全局的,不會在退出函數作用域的時候被析構。
接下來,使用二分法定位,發現問題就在process()這個函數體內了??墒沁@個函數體有數百行,該怎么查呢。
這時候只能用valgrind來幫忙了(沒聽過valgrind的同學自己google吧)。終于發現了一處數組訪問越界,我了個去,忙活了大半天就是為了這個錯誤……
問題是解決了,但是該怎么辦才能保證以后類似的問題不發生呢?
c++并不會檢查數組訪問是否越界,那我們該怎么做呢。
一個想法是,對于自定義的數據結構,重載(),對于下標運算,先assert一下,看看下標有沒有越界,但是對于內建的數組,或者stl容器,我就不知道有什么辦法可以在編譯時檢查,或者在運行出錯的時候能夠給出一個明確的錯誤信息。
如果有人對于這方面有啥心得體會,請不吝賜教!
浙公網安備 33010602011771號