区别是什么:

ptr = malloc(MAXELEMS * sizeof(char *));

And:

ptr = calloc(MAXELEMS, sizeof(char*));

什么时候使用calloc优于malloc或反之亦然?


当前回答

摘自Georg Hager的博客上的一篇文章,用calloc()进行有趣的基准测试

When allocating memory using calloc(), the amount of memory requested is not allocated right away. Instead, all pages that belong to the memory block are connected to a single page containing all zeroes by some MMU magic (links below). If such pages are only read (which was true for arrays b, c and d in the original version of the benchmark), the data is provided from the single zero page, which – of course – fits into cache. So much for memory-bound loop kernels. If a page gets written to (no matter how), a fault occurs, the “real” page is mapped and the zero page is copied to memory. This is called copy-on-write, a well-known optimization approach (that I even have taught multiple times in my C++ lectures). After that, the zero-read trick does not work any more for that page and this is why performance was so much lower after inserting the – supposedly redundant – init loop.

其他回答

malloc和calloc都分配内存,但calloc将所有位初始化为0,而malloc则不这样做。

可以说,Calloc相当于malloc + memset + 0(其中memset将指定的内存位设置为0)。

因此,如果不需要初始化为0,那么使用malloc可能会更快。

区别1:

Malloc()通常分配内存块,它是初始化的内存段。

Calloc()分配内存块并将所有内存块初始化为0。

区别2:

如果考虑malloc()语法,它只需要1个参数。考虑下面的例子:

data_type ptr = (cast_type *)malloc( sizeof(data_type)*no_of_blocks );

例如:如果你想为int类型分配10块内存,

int *ptr = (int *) malloc(sizeof(int) * 10 );

如果考虑calloc()语法,它将接受2个参数。考虑下面的例子:

data_type ptr = (cast_type *)calloc(no_of_blocks, (sizeof(data_type)));

例如:如果你想为int类型分配10块内存,并将所有这些初始化为0,

int *ptr = (int *) calloc(10, (sizeof(int)));

相似度:

malloc()和calloc()如果没有进行类型强制转换,默认情况下都会返回void* !

分配的内存块大小没有差异。Calloc只是用物理全零位模式填充内存块。在实践中,通常假设位于用calloc分配的内存块中的对象具有初始值,就像它们是用文字0初始化的一样,即整数的值应该是0,浮点变量的值应该是0.0,指针的值应该是适当的空指针值,等等。

然而,从学究的角度来看,calloc(以及memset(…, 0,…))只能保证正确地初始化unsigned char类型的对象(使用0)。其他所有内容都不能保证被正确初始化,并且可能包含所谓的陷阱表示,这会导致未定义的行为。换句话说,对于除unsigned char以外的任何类型,前面提到的全零位模式可能表示非法值,即陷阱表示。

后来,在C99标准的一个技术更正中,为所有整数类型定义了行为(这是有意义的)。也就是说,在当前的C语言中,你只能用calloc(和memset(…, 0,…))。从C语言的角度来看,在一般情况下使用它来初始化其他任何东西都会导致未定义的行为。

在实践中,calloc工作,我们都知道:),但是否想要使用它(考虑到上面的问题)取决于你。我个人更倾向于完全避免它,而是使用malloc并执行自己的初始化。

最后,另一个重要的细节是,calloc需要在内部计算最终的块大小,通过将元素大小乘以元素数量。在执行此操作时,calloc必须监视可能的算术溢出。如果无法正确计算请求的块大小,将导致分配不成功(空指针)。同时,您的malloc版本不会尝试监视溢出。它将分配一些“不可预测”的内存数量,以防发生溢出。

The documentation makes the calloc look like malloc, which just does zero-initialize the memory; this is not the primary difference! The idea of calloc is to abstract copy-on-write semantics for memory allocation. When you allocate memory with calloc it all maps to same physical page which is initialized to zero. When any of the pages of the allocated memory is written into a physical page is allocated. This is often used to make HUGE hash tables, for example since the parts of hash which are empty aren't backed by any extra memory (pages); they happily point to the single zero-initialized page, which can be even shared between processes.

任何对虚拟地址的写都被映射到一个页,如果该页是零页,则分配另一个物理页,将零页复制到那里,并将控制流返回给客户端进程。这与内存映射文件、虚拟内存等工作方式相同。它使用分页。

下面是一个关于这个主题的优化故事: http://blogs.fau.de/hager/2007/05/08/benchmarking-fun-with-calloc-and-zero-pages/

malloc()和calloc()是来自C标准库的函数,它们允许动态内存分配,这意味着它们都允许在运行时分配内存。

他们的原型如下:

void *malloc( size_t n);
void *calloc( size_t n, size_t t)

两者的区别主要有两点:

行为:malloc()分配一个内存块,不初始化它,从这个块中读取内容将导致垃圾值。另一方面,Calloc()分配一个内存块并将其初始化为0,显然读取这个块的内容将导致为0。 语法:malloc()有一个参数(要分配的大小),calloc()有两个参数(要分配的块的数量和每个块的大小)。

如果成功,两者的返回值都是指向已分配内存块的指针。否则返回NULL,表示内存分配失败。

例子:

int *arr;

// allocate memory for 10 integers with garbage values
arr = (int *)malloc(10 * sizeof(int)); 

// allocate memory for 10 integers and sets all of them to 0
arr = (int *)calloc(10, sizeof(int));

使用malloc()和memset()可以实现与calloc()相同的功能:

// allocate memory for 10 integers with garbage values   
arr= (int *)malloc(10 * sizeof(int));
// set all of them to 0
memset(arr, 0, 10 * sizeof(int)); 

注意malloc()最好比calloc()使用,因为它更快。如果需要对值进行零初始化,则使用calloc()。