C教程问题:calloc与malloc的区别

10
我正在按照这个教程 (http://theocacao.com/document.page/234) 进行学习。我对这个段落感到困惑,特别是与 calloc 相关的那些代码行:

我们还可以使用 malloc 函数的一个变体,称为 calloc。calloc 函数接受两个参数,一个是值计数,另一个是基本值大小。 它在返回指针之前还清除内存,这在避免某些情况下出现不可预测的行为和崩溃方面非常有用:

最后一行让我感到困惑。什么是清除内存?

4个回答

21

函数calloc将确保返回的内存中所有字节都设置为0。malloc没有这样的保证。它返回的数据可能是看似随机的数据。

区别对于数据成员的初始化非常有用。如果在结构体的所有值中,0都是一个很好的默认值,那么calloc可以简化结构体的创建。

Foo* pFoo = calloc(1, sizeof(Foo));

对比。

Foo* pFoo = malloc(sizeof(Foo));
pFoo->Value1 = 0;
pFoo->Value2 = 0;

为了简洁起见省略了空值检查。


由此产生的后果是,如果没有正确初始化内存,则会得到不可预测的结果。 - dmckee --- ex-moderator kitten
如果您也要使用realloc(),则必须处理额外内存未被清零的事实 - 因此,您可能需要确保初始化代码彻底地完成这项工作。显然,如果您使用calloc()分配内存并且永远不会使用realloc(),那么这就无关紧要了。 - Jonathan Leffler
1
将包含看似随机的数据 - 对于某些“随机”值。统计测试很可能能够将其与在范围0 ... UCHAR_MAX上均匀分布的离散随机变量的连续样本区分开来;-) - Steve Jessop

7

准确来说:

这是有用的,可以避免在某些情况下出现的不可预测的行为和崩溃。

应该改为:

这是有用的,可以隐藏在某些情况下出现的不可预测的行为和崩溃。


4
在这种情况下,“清除内存”的意思是用物理上的全零位模式填充它。请注意,从正式的角度来看,这种原始内存初始化仅保证适用于整数类型。也就是说,整数类型的对象保证会接收初始值为零。其他任何类型是否会被有意义地初始化则是实现定义的。(需要额外的标准超出了C标准的限制才能提供额外的保证,如POSIX、IEEE 754等)
至于在引文中描述的使用calloc“防止崩溃”是否有意义,则是另一个问题。我认为它确实可以改善懒惰程序员编写的代码的稳定性,因为它将由各种垃圾值触发的所有可能的意外行为折叠成由全零值触发的特定意外行为。

0

malloc()函数分配内存块,但不初始化已分配的内存。如果我们尝试访问内存块的内容,则会得到垃圾值。

calloc()函数分配并将已分配的内存初始化为零。如果我们尝试访问内存块的内容,则会得到0。

注意:如何使用malloc()函数作为calloc()函数?

可以通过使用string.h库的memset()函数来将malloc()函数用作calloc()函数,具体如下。

int *ptr;
ptr=malloc(size);
memset(ptr,0,size);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接