【发布时间】:2020-02-14 22:41:52
【问题描述】:
我正在开发四个基本内存分配例程 malloc、realloc、calloc 和 free(类似于 Electric Fence 的操作)的调试实现,以调试嵌入式系统上的堆损坏。没有资源来运行其他内存调试工具,或者其他工具不存在(例如,用于 PowerPC 的 LynxOS 7.0 附带 GCC 4.6.3,以及不包括 mtrace 的 glibc 和 libstdc++ 的专有实现函数族)。
以下是calloc的源码,来自GCC的libiberty中的calloc.c。
PTR
calloc (size_t nelem, size_t elsize)
{
register PTR ptr;
if (nelem == 0 || elsize == 0)
nelem = elsize = 1;
ptr = malloc (nelem * elsize);
if (ptr) bzero (ptr, nelem * elsize);
return ptr;
}
为什么nelem 和elsize 都设置为等于1,如果其中一个等于0?
如果我尝试分配 0 大小为 n 或 n 大小为 0 的块,这两种情况都不会导致总字节数为 0 的聚合分配,而不是 1字节?
【问题讨论】:
-
malloc和calloc按规范要求返回唯一值。 -
@KerrekSB 但是由于
malloc()已经有这个要求,calloc()不需要自己检查。 -
@Barmar 我想到了你的想法,“因为 malloc() 已经有这个要求,所以 calloc() 不需要自己的检查。”。此处与冗余检查的功能区别在于,通过在此处执行此操作,1 字节分配为零。如果没有
if (nelem == 0 || elsize == 0) nelem = elsize = 1;,分配将保持原样。 -
@chux 确实如此,但访问内存是未定义的行为,因此没有必要。
-
@Barmar 同意 UB,但这是一种称为 Electric Fence 的编码范例,可能需要确定性行为。