(原創) 為什麼有些東西要delete?有些又不用? (C/C++)

在C#、Java這種managed語言,因為有garbage collection,所以完全不用考慮free()或delete,但在C/C++,有時候要delete的,有時又不用,到底哪些改delete?哪些不用delete呢?

簡單的說,若要使用用到heap,就要手動去delete或free()!!

那什麼時候會用到heap呢?當你打算使用dynamic allocation時!!更白話一點,就是你用new或malloc()時,就必須自己手動去delete或free()!!

為什麼用到heap就必須手動處理呢?一般我們建立物件,如

1int i;
2Foo foo;


都是建在stack上,回想我們學資料結構(Data Structure)的stack,此時每個function就是stack中的一個element,當function結束,該element被提出就不見了,在裡面宣告的東西當然也跟這就不見了,OS可以重新取的記憶體資源繼續利用!!這種就都不需delete。

但是當你使用new或malloc()時,是建在heap上,所以當function結束時,該物件仍然可被存取,直到你下了delete或free()後,OS才可以重新取得記憶體資源繼續利用!!若你忘了寫delete,或因為程式流程錯誤而沒有跑到delete,導致OS永遠無法取得那塊記憶體,這就是所謂的Memory Leak了!!要一直等該程式永遠結束才會將記憶體還給OS,但別忘了很多程式是不會結束的,如service,driver,這些程式都是一直跑到OS結束才會結束,這類程式是否Memory Leak就是很嚴重的問題了!!這種都需要delete。

在C++中,凡使用new,都一律使用pointer,如

1int *= new int(5);
2Foo *foo = new Foo(5);
3int *ia = new int[5];


也可以說,當在C++使用pointer時,就必須手動去delete!!

一般來說,C++很少會用到int *i = new int(5)和Foo *foo = new Foo(5);的寫法,除非你想在function結束後繼續使用這個物件,但int *ia = new int[5];這種動態宣告array卻常見!!當然用STL的vector..等container更好,但為了效率考量,還是常常看到使用動態陣列的程式。

Conclusion
在Modern C++中,已經很少為了dynamic allocation使用pointer了,都是使用STL的container,因為可以避免memory leak,程式也比較優雅,但一些舊的程式碼,還是會看到使用new的程式碼,該學嗎?還是得學!!因為這也是Classic C++和C語言的一部分,別忘了effective C++的第一條,C++包含了C語言,OO C++,STL,template C++四大部分,就算自已不用new,pointer寫,也還是得看得懂別人寫的舊程式,算是C/C++的包袱吧!!所以只要用new,malloc()和pointer的,就得自己去delete,free()。

Reference
深度學習C++ 2nd, section 5.4 動態記憶體空間配置, p.99
C++ FAQ 2nd, FAQ 31.02, What is the easiest way to avoid memory leaks?

posted on 2007-02-22 15:41  真 OO无双  阅读(4765)  评论(0编辑  收藏  举报

导航