C 語言的內存管理如何比 C++ 的 RAII 靠譜?

這真的可能嗎?是怎麼做到的?

或者說,達到同樣的靠譜效果,C 語言和 C++ 哪個需要耗費的精力/代碼多?哪個看起來簡潔、緊湊?


你這個問題類似於「自己靠生物鐘準時起床如何比鬧鐘靠譜」。靠譜程度自行想像。


C有什麼內存管理…


謝邀,不是一個好問題。


有可能。

比如說你有一個數組放了一堆指針持有需要釋放的資源。現在你需要轉移這些資源。

如果這些指針都換成RAII/RRID對象你就會發現C++好蠢。

當然ptr_vector在這裡是更好的選擇。


rall屬於高級語言,c++即可以作為高級語言使用,又可以作為系統級語言使用,如果又要做系統級用,又要提供高級語言的特性,問題就來了。

至於c語言內存分配,最高境界的內存分配是沒有動態分配,根據系統需求,直接設計好內存規劃。比如一個路由器,系統要求支持1萬鏈接,那就直接1萬鏈接需要的內存規劃好,不用動態分配,動態釋放沒有意義,如果有人使用了這個內存,那麼可能達不到1萬鏈接的需求,如果沒有人使用,幹嘛要去釋放呢。

另外沒有一種演算法可以符合所有c語言動態分配要求,看不同的應用採用不同的分配演算法。用c去寫一套rall式的內存分配方式,除了好玩沒有啥用處。

至於內存泄露之類的問題,c有很多處理方式,計數器,內存邊界標記等,最重要的是這些往往是調試代碼,正式發布一般會取消,當然急著發布有問題的版本除外。


c語言沒有那麼多的高級特性,所以從語言層面上來說,要達到相似程度的簡潔肯定比較難。所以有人評論說是關公戰秦瓊。

從內存管理角度看,我們如果能夠把內存分配和釋放關聯在一起,或者保證資源的請求和釋放是成對出現的,就可以保證內存不泄漏。

那麼簡化的辦法就是保證任何請求/釋放都是在一個簡短順序執行的上下文順序排放就可以了。因為c沒有異常,所以在順序執行函數內部我們是可以通過一些手段來逼近這一要求的,比如所謂的某些關鍵場合下的代碼要求函數只有一個出口,這樣,之前分配的資源就能夠比較容易確保都得到釋放。

更進一步的,如果是共享的資源,分布在不同的並發/非同步的函數中訪問,那麼和c++一樣,我們可以使用智能指針,只需要保證智能指針的獲取和釋放成對即可。

總體上,一些好的編程模式和手段之下,保證內存沒有泄漏這件事情,比保證程序邏輯正確來說,要容易的多,也容易檢查的多。很多人抱怨內存難以管理,那麼他們的程序正確性更加值得懷疑,儘管很多時候是因為編程手段無法對所需問題做極簡化的抽象所致。這一點,除了一個不堪大用的異常之外,在引入函數式編程手段前的c++比c來說,並好不了太多。


沒有不靠譜的機制,只有不靠譜的人。


這個問得就關公戰秦瓊啦。

如果放到 C++ 環境里,那麼隨便哪裡拋個異常,C 語言內存管理就死翹翹了,內存泄漏妥妥的。

如果放到 C 環境里,那麼 RAII 根本沒法實現,實現必定引入異常,然後異常大鬧天宮,也就沒啥了……


推薦閱讀:

輸出測試時有哪些有趣的字元串可以用來代替「hello, world"?
有些語言用{},有些語言用end,大家怎麼看?
為什麼unordered_map源碼中的need_rehash函數只是將桶容量擴到下一個最小的素數?
C++里為什麼要添加lambda?是C++本身的什麼問題造成的?
智能指針有什麼不足之處?

TAG:C編程語言 | 內存管理 | C | CC |