[英]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;
}
为什么nelem
和elsize
都设置为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.