【问题标题】:Why memory isn't zero out from malloc?为什么内存不是从 malloc 中归零?
【发布时间】:2015-12-24 23:23:01
【问题描述】:

我在书中看过:

动态内存分配器维护进程的虚拟区域 内存称为堆。细节因系统而异,但 不失一般性,我们将假设 堆是 在未初始化之后立即开始的零需求内存 bss 区域并向上增长(朝向更高的地址)。

所以,我很困惑为什么堆中的内存没有初始化为零。 更准确地说,我的意思是 malloc 返回的一块内存。

【问题讨论】:

  • 这是一种不同的“堆”。事实上,C 标准没有“堆”的概念。这个词根据上下文有很多不同的含义。
  • 因为它不是必需的。有calloc
  • 为什么会这样?没有任何优势,而且对性能的影响可能很大。如果您希望将动态内存初始化为零,请使用calloc(3)
  • 什么是“书”?它是对 C 工作原理的权威描述吗?从“不失一般性”等短语的使用来看,它似乎更侧重于教授系统如何工作,而不是具体系统如何
  • malloc 不一定从堆中请求新内存。它还可以返回您的程序为freed 的内存。

标签: c memory-management


【解决方案1】:

本书所描述的是一个内存分配如何工作的例子。这是一个非常常见的例子,但有些平台的工作方式不同。它描述了一个带有虚拟内存的多任务平台。

多任务平台上的内存分配有两个方面:首先任务从操作系统接收一些内存;然后任务本身管理自己的内存。您引用的段落描述了第一步。

在这个典型的平台上,当任务向操作系统请求更多内存时(通过对内核进行系统调用,例如在传统 Unix 系统上使用brk system call),操作系统的内核会找到一些物理内存不被任何其他任务使用,在其内部数据结构中将其标记为正在使用,并在称为 BSS 或堆的连续虚拟地址段的末尾在任务的内存映射中引用它们。此外,此内存被清零,因此该任务不会读取另一个任务留下的一些数据。

malloc 函数通过分配堆区域的块来工作。它完全在任务的堆内工作。如果堆已满,它只会进行系统调用以获得更多内存。在大多数平台上,malloc 函数不会覆盖它分配的内存,以提高性能。所以当一个内存块在从操作系统获得后第一次使用时,它会碰巧被清零。但是如果内存已经在任务内部使用了,因为它是用malloc 获得的,然后用free 释放,并被另一个malloc 重用,那么内存将包含任务第一次放在那里的任何东西。

【讨论】:

  • 只有你明白我的意思。谢谢。
【解决方案2】:

长话短说,因为malloc() 不是这样设计的。

从堆分配内存时,它只是返回一个指向具有请求大小的内存的指针,它不关心内存位置的(现有)内容。如果内存先前被其他调用分配然后释放,则 实际 内存可能仍保存以前的数据。相同的内存位置,如果在下一次调用malloc() 时重新分配,它很可能包含旧数据(在最后一次调用中变得不确定)。它实际上节省了将分配的内存清零的开销。

当您要立即覆盖分配的内存时,malloc() 可以为您节省不必要的内存位置清零开销。

OTOH,calloc() 会根据需要对分配的内存进行零初始化。

【讨论】:

    猜你喜欢
    • 2011-03-30
    • 2021-10-16
    • 2010-12-09
    • 1970-01-01
    • 1970-01-01
    • 2012-03-26
    • 2020-02-12
    • 2016-07-18
    • 2018-10-02
    相关资源
    最近更新 更多