標籤

C++ (12) Linux (6) MacOSX (4) Makefile (3) Matlab (3) Ubuntu (3) Android (2) C (1) Refactoring (1)

2011年11月13日 星期日

[c++] 資料結構ADT之容易Crash的點

每次建新的class時
都很開心地寫了一堆member function
結果function明明就沒有問題
可是一用就segmentation fault (囧)
而且通常也cout不出個所以然...
(當然也是可以用gdb啦...)

下面列了幾個很容易crash的點:

<狀況一> 忘了寫copy constructor 和 operator =


解釋:
        當data member不是內建資料型態或是pointer時,這兩個一定要記得實作。因為很多ADT都事先宣告,之後才慢慢塞資料進去。例如:DList dlist; dlist = load_from_file(...)之類的寫法,就樣就已經用到operator = 囉!(不要以為DList dlist = load_from_file(...)就沒有用到喔!)

症狀:
最典型的就是segmentation fault和pointer being freed was not allocated。而且通常還cout不出個所以然。因為像是陣列存取到不該存取的地方,「不一定」會crash,有時會有時不會,端看那部分的記憶體被分給誰了。遇到這種情況真的打爆電腦。前者通常是存取到不該存取的地方,後者通常是暫存變數被destructor呼叫delete刪到不該存取的地方。

<狀況二> 忘了把設pointer-type data member為NULL

解釋:
記得若有data member的型態是pointer的話,一定一定要在constructor內先設為NULL!因為通常遇到pointer,又雞猴想省空間所以我一定要清乾淨的話,會在destructor裡寫delete來釋放。而且通常都會很聰明的加上if(arr != NULL)來避開delete掉NULL的慘劇(其實根本不會有慘劇,NULL可以被delete而且也不會有segmentation fault)。結果就是會主觀地強烈認為一定不是crash在那個點,而事實上pointer沒被initialize成NULL的話,一定是garbage,所以不會是NULL,所以會被delete,然後就爆了

症狀:
還滿好認的。通常會出現pointer being freed was not allocated的字樣。

<狀況三> 雞猴用memcpy來省code行數

解釋:
好發在class template裡。通常自己寫了一個很猛的array list或其他adt後,一定會很想把它做成template,這樣就可以支援int, double, ...。不過哪一天你用了string哩丟無災安怎死了...,一開始寫memcpy因為int, double是內建資料型態,全部memset/memcpy就好了,有帶pointer的資料型態通通會crash!!

症狀:
直接segmentation fault,別無死法。
(BTW string的operator == 也不是比較字串的內容,要用compare,也常遇到)

沒有留言:

張貼留言