2015-09-27 62 views
0

我讀的書:爲什麼內存不從malloc中清零?

的動態內存分配器維護一個進程的虛擬內存 被稱爲堆的區域。細節因系統而異,但在不失一般性的情況下,我們將假定堆是 需求零存儲區的區域,其在未初始化的區域之後立即開始並向上(向更高地址)增長。

所以,我很困惑爲什麼堆的內存沒有初始化爲零。 更確切地說,我的意思是由malloc返回的一塊內存。

+1

這是一種不同的「堆」。事實上,C標準沒有「堆」的概念。這個詞意味着許多不同的事情取決於上下文。 –

+9

因爲它不是必需的。這裏有'calloc'。 –

+1

爲什麼會這樣?沒有優勢,性能受到重創。如果你想動態內存初始化爲零,那麼使用'calloc(3)'。 –

回答

1

這本書描述的是內存分配如何工作的例子。這是一個非常常見的例子,但有些平臺的工作方式不同。它描述了一個具有虛擬內存的多任務平臺。

多任務平臺上的內存分配有兩個方面:首先任務從操作系統接收一些內存;那麼任務本身管理自己的記憶。你引用的段落描述了第一步。

在這個典型的平臺上,當任務要求操作系統獲得更多內存(通過對內核進行系統調用,例如在傳統Unix系統上使用brk system call)時,操作系統的內核會找到一些物理內存不被任何其他任務使用,在內部數據結構中將其標記爲正在使用,並在稱爲BSS或堆的連續虛擬地址段末尾的任務內存映射中引用它們。此外,該內存被清零,以便該任務不會讀取其他任務遺留的一些數據。

malloc函數通過分配堆區的塊來工作。它完全在任務的堆內工作。如果堆滿了,它只會進行系統調用以獲得更多內存。在大多數平臺上,malloc函數不會覆蓋它分配的內存以提高性能。所以當從操作系統中獲得第一次使用的內存塊時,它就會被清零。但是如果內存已經在任務內部使用,因爲它已經通過malloc獲得,然後用free釋放,並被另一個malloc重複使用,那麼內存將包含第一次放置的任務。

+0

只有你明白我的意思。謝謝。 – Gilgamesz

0

長話短說,因爲malloc()不是那樣設計的。

從堆中分配內存時,它只是返回一個指向內存大小的指針,它不會影響內存位置的(現有)內容。如果內存先前被其他呼叫分配後再釋放,則存在內存仍然保留先前數據的可能性。相同的內存位置,如果通過下一次調用malloc()重新分配,它可能包含舊數據(在上次調用中變得不確定)。它實際上節省了清零分配內存的開銷。

當您立即要覆蓋分配的內存時,malloc()可以爲您節省內存位置清零的不必要開銷。

OTOH,calloc()會對分配的內存進行零初始化,如果您需要的話。