簡體   English   中英

C:這段代碼如何導致釋放malloc占用的空間?

[英]C: how does this code result in the freeing of malloc-ed space?

我正在通過Zed Shaw的Learn C The Hard Way進行學習,並且對練習19有疑問(請參見下面的描述和鏈接)。

皮包骨頭:在讀取/輸入代碼時,令我驚訝的是,在程序執行開始時創建各種對象時,我們從未顯式釋放我們分配的內存(下面將詳細介紹)。 由valgrind確認:valgrind報告在執行開始時分配了12個塊(或608字節)。 在程序終止時,這些塊被報告為丟失(大多數間接丟失,有些直接丟失)。

那么...此代碼是否代表了良好(甚至可以接受)的內存管理技術? 還是缺少內存重新分配是一個錯誤? 似乎是后者,但由於我是C n00b,因此希望征詢他人的意見。

(鑒於伴隨的練習沒有一個涉及更改程序以確保我們釋放malloc分配的內存,因此我認為所發布的代碼是合理的,即代表良好的編碼做法。)

我在下面提供了練習的概述。 我沒有完整地發布代碼,而是提供了鏈接: http : //c.learncodethehardway.org/book/ex19.html

(Mods:很抱歉,如果不是通過鏈接鏈接到外部網站,請lmk,我將其刪除,由於潛在的版權問題,我只是不想復制發布在他網站上的資料。)


運動概述:

練習是制作一個簡單的基於文本的RPG,用戶可以在其中(i)選擇從一個房間移到另一個房間(即,從任何一個房間,您都可以選擇向北/向南/向東/向西走或走一部分走) (ii)選擇攻擊怪物(在其中一個房間中)。 實施的簡要總結(關注相關部分)如下:

  1. 我們在鏈接頁面的object.h和object.c文件中定義一個type(+ struct)“ Object”,其中包括(除其他功能外)一個構造函數,該構造函數調用“ malloc”和一個析構函數(可能不包含)技術術語),稱為“免費”。
  2. 在ex19.h文件中,我們繼續定義以下類型(+結構):地圖,房間和怪物,每個類型都包含一個“對象”(即我們在object.h和object.c中定義的內容)。 )以及其他一些內容。
  3. 游戲流程在ex19.c文件中定義。 在此文件中,我們創建了地圖,怪物和幾個房間的實例。

如您所見,我們從不會調用用於為Map,Monster和Room對象分配內存的函數(在object.h / object.c中聲明/定義的“ free”或“ Object_destroy”函數均未分配)。


注意:下面的Valgrind輸出是我從站點復制粘貼的代碼的結果; 我確保不要使用文件的重新鍵入版本,以免引入錯誤。

Valgrind輸出:

==10184== 
==10184== HEAP SUMMARY:
==10184==     in use at exit: 608 bytes in 12 blocks
==10184==   total heap usage: 12 allocs, 0 frees, 608 bytes allocated
==10184== 
==10184== 608 (64 direct, 544 indirect) bytes in 1 blocks are definitely lost in loss record 12 of 12
==10184==    at 0x4C2C934: calloc (vg_replace_malloc.c:623)
==10184==    by 0x400FCF: Object_new (object.c:52)
==10184==    by 0x400E53: main (ex19.c:206)
==10184== 
==10184== LEAK SUMMARY:
==10184==    definitely lost: 64 bytes in 1 blocks
==10184==    indirectly lost: 544 bytes in 11 blocks
==10184==      possibly lost: 0 bytes in 0 blocks
==10184==    still reachable: 0 bytes in 0 blocks
==10184==         suppressed: 0 bytes in 0 blocks
==10184== 
==10184== For counts of detected and suppressed errors, rerun with: -v
==10184== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

這很不好,但是在練習中很常見。 通常,他們說沒關系,因為OS將在進程終止后釋放所有內存。 沒錯,但是您絕對不應該在生產代碼中依靠它。

因此,我建議您從一開始就嘗試編寫良好的代碼,並顯式釋放所有內存塊。

更新

這不僅與效率有關,還與在設計應用程序時做出適當的決定有關。 例如,在此示例應用程序中,應該釋放內存,在怪物死后,房間應該銷毀它們擁有的對象,而地圖應該銷毀它的房間。 這不僅是您編寫的應用程序,還只是在嘗試幾次后將其丟棄。 它是一個庫,應該由其他人使用。 換句話說,這就是玩具應用程序和可以在服務器24/7/365上使用的實際生產代碼之間的區別。 那就是優秀的程序員和猴子編碼器之間的區別。

ivg所說的相反,這是一個壞主意,要在打撈人員開始之前整齊地掃地板並帶出垃圾來放縱OCD

您會不必要地拖延人們,使人們無休止。

(顯然,這僅適用於破壞工作人員已過時的工作,例如在具有功能性內存保護功能的任何平台上釋放內存。此外,在編程練習中,遍及所有樓層有時是您應該學習的內容之一。)

雷蒙德·陳(Raymond Chen)關於該主題的博客文章: http : //blogs.msdn.com/b/oldnewthing/archive/2012/01/05/10253268.aspx

引用 Hans Boehm(Boehm GC)的話:

分配誤區4:非垃圾收集程序應始終釋放其分配的所有內存。

真相:頻繁執行的代碼中省略的重分配會導致泄漏增加。 它們很少被接受。 但是在程序退出之前保留分配的內存最多的程序通常會在沒有任何介入釋放的情況下執行得更好。 如果沒有免費的內存,則Malloc易於實現。

在大多數情況下, 在程序退出之前釋放內存是沒有意義的。 操作系統仍會收回它。 自由會觸碰並翻頁死物; 操作系統不會。

結果:請小心“泄漏檢測器”,它會統計分配情況。 一些“泄漏”是好的!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM