我讀的書:爲什麼內存不從malloc中清零?
的動態內存分配器維護一個進程的虛擬內存 被稱爲堆的區域。細節因系統而異,但在不失一般性的情況下,我們將假定堆是 需求零存儲區的區域,其在未初始化的區域之後立即開始並向上(向更高地址)增長。
所以,我很困惑爲什麼堆的內存沒有初始化爲零。 更確切地說,我的意思是由malloc返回的一塊內存。
我讀的書:爲什麼內存不從malloc中清零?
的動態內存分配器維護一個進程的虛擬內存 被稱爲堆的區域。細節因系統而異,但在不失一般性的情況下,我們將假定堆是 需求零存儲區的區域,其在未初始化的區域之後立即開始並向上(向更高地址)增長。
所以,我很困惑爲什麼堆的內存沒有初始化爲零。 更確切地說,我的意思是由malloc返回的一塊內存。
這本書描述的是內存分配如何工作的例子。這是一個非常常見的例子,但有些平臺的工作方式不同。它描述了一個具有虛擬內存的多任務平臺。
多任務平臺上的內存分配有兩個方面:首先任務從操作系統接收一些內存;那麼任務本身管理自己的記憶。你引用的段落描述了第一步。
在這個典型的平臺上,當任務要求操作系統獲得更多內存(通過對內核進行系統調用,例如在傳統Unix系統上使用brk
system call)時,操作系統的內核會找到一些物理內存不被任何其他任務使用,在內部數據結構中將其標記爲正在使用,並在稱爲BSS或堆的連續虛擬地址段末尾的任務內存映射中引用它們。此外,該內存被清零,以便該任務不會讀取其他任務遺留的一些數據。
malloc
函數通過分配堆區的塊來工作。它完全在任務的堆內工作。如果堆滿了,它只會進行系統調用以獲得更多內存。在大多數平臺上,malloc
函數不會覆蓋它分配的內存以提高性能。所以當從操作系統中獲得第一次使用的內存塊時,它就會被清零。但是如果內存已經在任務內部使用,因爲它已經通過malloc
獲得,然後用free
釋放,並被另一個malloc
重複使用,那麼內存將包含第一次放置的任務。
只有你明白我的意思。謝謝。 – Gilgamesz
長話短說,因爲malloc()
不是那樣設計的。
從堆中分配內存時,它只是返回一個指向內存大小的指針,它不會影響內存位置的(現有)內容。如果內存先前被其他呼叫分配後再釋放,則存在內存仍然保留先前數據的可能性。相同的內存位置,如果通過下一次調用malloc()
重新分配,它可能包含舊數據(在上次調用中變得不確定)。它實際上節省了清零分配內存的開銷。
當您立即要覆蓋分配的內存時,malloc()
可以爲您節省內存位置清零的不必要開銷。
OTOH,calloc()
會對分配的內存進行零初始化,如果您需要的話。
這是一種不同的「堆」。事實上,C標準沒有「堆」的概念。這個詞意味着許多不同的事情取決於上下文。 –
因爲它不是必需的。這裏有'calloc'。 –
爲什麼會這樣?沒有優勢,性能受到重創。如果你想動態內存初始化爲零,那麼使用'calloc(3)'。 –