两者之间有什么区别:
ptr = (char **) malloc (MAXELEMS * sizeof(char *));
要么:
ptr = (char **) calloc (MAXELEMS, sizeof(char*));
什么时候在 malloc 上使用 calloc 是个好主意,反之亦然?
calloc()
对缓冲区进行零初始化,而malloc()
使内存未初始化。
编辑:
将内存清零可能会花费一些时间,因此如果性能存在问题,则可能要使用malloc()
。如果初始化内存更重要,请使用calloc()
。例如, calloc()
可能会节省您对memset()
的调用。
鲜为人知的区别是,在具有乐观内存分配的操作系统(如 Linux)中,直到程序真正接触malloc
为止, malloc
返回的指针才由实内存支持。
calloc
确实确实触及了内存(它在上面写了零),因此您可以确定操作系统将用实际的 RAM(或交换)来支持分配。这也是为什么它比 malloc 慢的原因(不仅必须将其清零,而且操作系统还必须通过交换其他进程来找到合适的内存区域)
例如,请参见此 SO 问题以进一步讨论 malloc 的行为
calloc
一个经常被忽略的优点是(符合要求的实现)它将帮助您防止整数溢出漏洞。比较:
size_t count = get_int32(file);
struct foo *bar = malloc(count * sizeof *bar);
与
size_t count = get_int32(file);
struct foo *bar = calloc(count, sizeof *bar);
如果count
大于SIZE_MAX/sizeof *bar
,则前者可能会导致很小的分配并导致随后的缓冲区溢出。在这种情况下,后者将自动失败,因为无法创建较大的对象。
当然,您可能必须注意那些不符合标准的实现,而这些实现只是忽略了溢出的可能性... 如果在您所针对的平台上存在问题,则无论如何都必须进行手动测试以检查溢出。