繁体   English   中英

如果 nelem 或 elsize == 零,为什么 calloc 分配 1 个字节?

[英]Why does calloc allocate 1 byte if nelem or elsize == zero?

I am working to develop debug implementations of the four basic memory allocation routines malloc , realloc , calloc , and free (similar in operation to Electric Fence) to debug heap corruption on embedded systems which do not have the resources to run other memory debugging tools,或者其他工具不存在(例如,LynxOS 7.0 for PowerPC 附带 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;
}

为什么nelemelsize都设置为1如果其中一个等于0

如果我尝试分配0个大小为n的块或n大小为0的块,这两种情况都不会导致总分配为0个总字节,而不是1个字节?

如果 nelem 或 elsize == 零,为什么 calloc 分配 1 个字节?

以减少歧义。

calloc(0, x), calloc(x, 0), malloc(0)成功时,可能返回NULL或非NULL指针。 在这两种情况下,指针可能不会被取消引用而不会导致未定义的行为(UB)。

不成功时,返回NULL指针。

通过确保分配大小大于 0,在返回NULL时没有歧义 -calloc()分配失败。


请注意,更好的 function 也可以检测产品溢出。

if (nelem == 0 || elsize == 0) {
  nelem = elsize = 1;
} else if (SIZE_MAX/nelem > elsize) {
  return NULL;  // Too much for this implementation
}
...

进一步思考Electric_Fence

我希望该项目的malloc(0)也能确保不分配 0 字节。 然而,只需调用ptr = malloc (0); if (ptr) bzero (ptr, 0); ptr = malloc (0); if (ptr) bzero (ptr, 0); 不会将 1 字节分配归零。 if (nelem == 0 || elsize == 0) nelem = elsize = 1; 确保分配至少为 1 个字节并且分配为零。

是的,这只是糟糕的代码,这在 libiberty/gnulib/etc 中并不意外。 据我了解,如果malloc(0)返回 null 指针而不是每次调用的唯一指针,它们已经替换了malloc ,因此我认为没有任何充分的理由让calloc将 1 传递给malloc ,而不是传递 7 152EDCC3A08D31破坏/破坏调试工具,如消毒剂,它可以告诉您是否无意中取消引用指向“零元素数组”的指针。

该代码也非常危险,因为它不检查乘法是否溢出。 为此,需要任何正确的calloc实现。

TL;DR:这个代码是垃圾。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM