2010-03-19 73 views
9

我是C的初學者。在閱讀git的源代碼時,我發現這個包裝函數在malloc左右。包裝malloc - C

void *xmalloc(size_t size) 
{ 
    void *ret = malloc(size); 
    if (!ret && !size) 
     ret = malloc(1); 
    if (!ret) { 
     release_pack_memory(size, -1); 
     ret = malloc(size); 
     if (!ret && !size) 
      ret = malloc(1); 
     if (!ret) 
      die("Out of memory, malloc failed"); 
    } 
#ifdef XMALLOC_POISON 
    memset(ret, 0xA5, size); 
#endif 
    return ret; 
} 

問題

  1. 我不明白爲什麼他們使用malloc(1)
  2. release_pack_memory做什麼,我無法在整個源代碼中找到這個函數的實現。
  3. #ifdef XMALLOC_POISON memset(ret, 0xA5, size);做什麼?

我打算在我的項目中重用此功能。這是一個很好的包裝malloc

任何幫助將是偉大的。

+7

榮譽設定好的內存包裝的讀取現有的複雜程序的代碼 - 我希望更多的開發商這樣做。 – Lars 2010-03-19 18:38:38

+3

對於問題2:它的定義是在sha1_file.c中(大概是用於內存來處理git的包對象),它的原型在git-compat-util.h中。 (提示:只要你在git的源代碼中查看,使用'git grep release_pack_memory'找到它!) – Cascabel 2010-03-19 18:40:21

+1

@Lars:謝謝。 @Jefromi:關於'git grep'的好處。 – 2010-03-19 18:54:32

回答

3
  1. malloc(0)不適用於所有的平臺,在這種情況下,會改爲使用一個字節的分配。允許分配0長度的存儲塊可以簡化程序的高級邏輯。

  2. 不知道。

  3. 通過使用非零值填充分配的內存,在沒有正確初始化的情況下使用內存的程序中更容易找到錯誤:在這種情況下,程序幾乎會立即崩潰。由於填充內存需要時間,所以它被封裝在一個預處理器定義中,所以它只在需要時編譯。

+1

'malloc(0)'的行爲是實現定義的。它要麼返回一個NULL指針,要麼返回一個非空指針指向零字節的數據(當然,你永遠不能解引用)。 C99§7.20.3內存管理函數:「如果所請求的空間大小爲零,則行爲是實現定義的: 或者返回一個空指針,或者行爲就好像大小是非零值一些 ,除了返回的指針不應該被用來訪問一個對象。「 – 2010-03-30 06:59:03

2

問題1:

標準沒有定義的malloc(0)行爲。這可能會返回一個有效的指針,也可能返回NULL。不同的實現處理方式有所不同,因此代碼將回退到malloc(1)以獲得一致的行爲。

問題3:

它設置緩衝區的內容,以「怪」事。這樣,你的代碼有希望不依賴於具體內容(malloc不保證)。

+0

你是否建議使用這個包裝? – 2010-03-19 18:52:26

+0

@Appu - 將0改爲1並且執行memset很好。 OOM政策的死亡取決於你在寫什麼。該策略對於執行一件事並退出的命令行實用程序來說很好。對於長期服務的服務器,策略可能會也可能不會(您想要退出該過程,還是希望清理當前的請求並再次嘗試)?該政策對於通用圖書館是不可接受的,因爲關於OOM的政策應由主應用程序決定。 – 2010-03-19 19:05:38

+0

好點。我將要寫的代碼是一個圖書館。所以我認爲我應該避免「死亡」。 – 2010-03-19 19:07:21

1

我不熟悉這個包裝但這裏是它做

1 - 如果size = 0指定於是分配1個字節,而不是如果是底層的malloc沒有這樣做

這大概是這樣做呼叫者仍然可以做免費的就可以了(如realloc的)

2我認爲它試圖迫使底層的內存子系統來尋找記憶困難

3 XMALLOC_POISON力緩衝到已知狀態 這是常見的做法,以防止和檢測未初始化數據造成的奇怪錯誤

其次 - 爲什麼要打包malloc。從想要做什麼開始,然後實施它或複製實施。用於包裝的malloc原因

  1. 泄漏檢測
  2. 使用情況分析
  3. 內存池
  4. 調試(如XMALLOC_POISON)
  5. 強制檢查

幾乎所有的這些都可以用做valgrind - 它的功能更多。

「編寫可靠的代碼的書有1,4和5

+0

感謝您的回答。老實說,我在C世界有點迷路。所以爲了避免我犯錯誤,我正在閱讀其他程序代碼並找出他們如何編寫代碼。 – 2010-03-19 18:51:55

+2

「這大概是爲了讓調用者仍然可以自由地做到這一點」 - 您仍然可以在空指針上調用free或realloc。我不知道git的源代碼,但更有可能的是爲了確保調用者將0返回作爲錯誤來處理,即使輸入爲0也是如此。或者可能爲了確保指向不同0-大小分配比較不同(「這不是你的零大小的緩衝區,所以一定不能是你的行李箱!」)。 – 2010-03-19 20:04:09