我在书中读过:
动态内存分配器维护进程的虚拟区域 内存称为堆。细节因系统而异,但是 不失一般性,我们假设堆是一个区域 在未初始化之后立即开始的需求零记忆 bss区域并向上增长(朝向更高的地址)。
所以,我很困惑为什么来自堆的内存没有用零初始化。 更确切地说,我的意思是malloc返回的一块内存。
答案 0 :(得分:1)
本书描述的是内存分配如何工作的一个例子。这是一个非常常见的例子,但有些平台的工作方式不同。它描述了一个带有虚拟内存的多任务平台。
多任务平台上的内存分配有两个方面:首先,任务从操作系统接收一些内存;然后任务本身管理自己的记忆。您引用的段落描述了第一步。
在这个典型的平台上,当任务要求操作系统获得更多内存时(通过对内核进行系统调用,例如在传统的Unix系统上使用brk
system call),操作系统的内核会发现一些内存任何其他任务都没有使用的物理内存,将其内部数据结构标记为正在使用中,并在名为BSS的连续虚拟地址段末尾的任务内存映射中引用它们或堆。此外,这个内存被清零,以便任务不会读取另一个任务遗留下来的一些数据。
malloc
函数通过分配堆区域的块来工作。它完全在任务堆内部工作。如果堆已满,它只进行系统调用以获取更多内存。在大多数平台上,malloc
函数不会覆盖它分配的内存,以提高性能。因此,当从操作系统获得内存块后第一次使用它时,它就会被清零。但是如果内存已经在任务中使用,因为它是使用malloc
获得的,然后使用free
释放,并由另一个malloc
重用,那么内存将包含无论第一次把任务放在那里。
答案 1 :(得分:0)
简而言之,因为malloc()
不是那样设计的。
从堆中分配内存时,它只返回一个指向具有请求大小的内存的指针,它不会打扰内存位置的(现有)内容。如果以前通过某个其他调用分配了内存然后释放,则实际内存可能仍然保留以前的数据。相同的内存位置,如果通过下一次调用malloc()
重新分配,它可能很好地包含旧数据(在最后一次调用中变得不确定)。它实际上节省了将分配的内存清零的开销。
如果您要立即覆盖已分配的内存,malloc()
可以为您节省内存位置的不必要开销。
OTOH,calloc()
执行已分配内存的零初始化,如果需要的话。