【发布时间】:2021-01-14 20:44:39
【问题描述】:
我们知道虽然.bss 内存位置(例如未初始化的全局C 变量)总是由加载器初始化为零,但堆内存并非如此。一个常见的错误是假设堆内存被初始化为零。
但是mmap获得的分配内存呢?我们可以通过调用mmap来请求堆内存,将堆中的一个区域映射到一个匿名文件(需求零页),那么在这种情况下我们可以安全地假设堆内存初始化为零?
而且,malloc 实际上在内部调用mmap 来请求内存用于大尺寸的分配,而对于小尺寸的分配,malloc 仍然在内部调用sbrk/brk。对于后者,我们当然不能假设堆内存被初始化为零。
所以当malloc 在内部实际调用mmap 时,我们仍然可以假设堆内存初始化为零?我知道这仍然不是一个好的做法,我们不应该在所有情况下都阅读假设 0,但我只是想确保我的理论是正确的,以便我知道我对 mmap 的理解是正确的。
【问题讨论】:
-
如果你想保证内存设置为零,我建议你使用
calloc。 -
我没有资格回答这个问题,但不要假设任何没有记录的内容。
-
谁说“malloc 内部仍然调用 sbrk/brk”?对于某些特定的实现可能是这样。
-
如果未初始化的变量进入
.bss,那么它们被零初始化。 如果。这是一个有效的编译器选择,因为您可以覆盖这些零,而 C 仅保证未初始化的变量是可写的。你不能假设未初始化的变量是可读的,更不用说值为零了。 -
@MSalters 6.9.2/2:“具有文件范围的对象的标识符声明,没有初始化程序,没有存储类说明符或存储类说明符
static, 构成一个暂定定义。如果一个翻译单元包含一个或多个标识符的暂定定义,并且该翻译单元不包含该标识符的外部定义,则行为与翻译单元包含该标识符的文件范围声明,复合类型截至翻译单元的末尾,初始值设定项等于 0。"?
标签: c heap-memory virtual-memory