区别是什么:

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

And:

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

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


当前回答

Calloc一般是malloc+memset为0

显式使用malloc+memset通常会稍微好一点,特别是当你在做以下事情时:

ptr=malloc(sizeof(Item));
memset(ptr, 0, sizeof(Item));

That is better because sizeof(Item) is know to the compiler at compile time and the compiler will in most cases replace it with the best possible instructions to zero memory. On the other hand if memset is happening in calloc, the parameter size of the allocation is not compiled in in the calloc code and real memset is often called, which would typically contain code to do byte-by-byte fill up until long boundary, than cycle to fill up memory in sizeof(long) chunks and finally byte-by-byte fill up of the remaining space. Even if the allocator is smart enough to call some aligned_memset it will still be a generic loop.

一个值得注意的例外是,当您对一个非常大的内存块(一些power__2kb)执行malloc/calloc时,在这种情况下,可以直接从内核进行分配。由于操作系统内核通常会出于安全原因将它们放弃的所有内存归零,足够聪明的calloc可能只返回内存,而不进行额外的归零。同样,如果你只是分配一些你知道很小的东西,那么在性能方面使用malloc+memset可能会更好。

其他回答

有两个不同之处。 首先,是参数的数量。Malloc()接受一个参数(以字节为单位的内存需求),而calloc()需要两个参数。 其次,malloc()不会初始化分配的内存,而calloc()会将分配的内存初始化为ZERO。

Calloc()分配一个内存区域,长度将是其参数的乘积。calloc用0填充内存,并返回指向第一个字节的指针。如果它不能找到足够的空间,它返回一个NULL指针。

语法:ptr_var = calloc(no_of_blocks, size_of_each_block); 即ptr_var = calloc(n, s);

malloc()分配REQUSTED SIZE的单个内存块,并返回指向第一个字节的指针。如果它无法找到所请求的内存量,它返回一个空指针。

语法:ptr_var = malloc(Size_in_bytes); malloc()函数有一个参数,即分配的字节数,而calloc()函数有两个参数,一个是元素的数量,另一个是为每个元素分配的字节数。另外,calloc()将分配的空间初始化为0,而malloc()不会。

一个不太为人所知的区别是,在具有乐观内存分配的操作系统(如Linux)中,由malloc返回的指针直到程序实际接触它时才得到实际内存的支持。

calloc确实会接触内存(它会在内存上写0),因此您可以确定操作系统正在用实际的RAM(或swap)支持分配。这也是为什么它比malloc慢的原因(它不仅必须将它归零,操作系统还必须通过交换其他进程来找到合适的内存区域)

例如,请参阅这个SO问题以进一步讨论malloc的行为

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()。

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

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

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

Calloc一般是malloc+memset为0

显式使用malloc+memset通常会稍微好一点,特别是当你在做以下事情时:

ptr=malloc(sizeof(Item));
memset(ptr, 0, sizeof(Item));

That is better because sizeof(Item) is know to the compiler at compile time and the compiler will in most cases replace it with the best possible instructions to zero memory. On the other hand if memset is happening in calloc, the parameter size of the allocation is not compiled in in the calloc code and real memset is often called, which would typically contain code to do byte-by-byte fill up until long boundary, than cycle to fill up memory in sizeof(long) chunks and finally byte-by-byte fill up of the remaining space. Even if the allocator is smart enough to call some aligned_memset it will still be a generic loop.

一个值得注意的例外是,当您对一个非常大的内存块(一些power__2kb)执行malloc/calloc时,在这种情况下,可以直接从内核进行分配。由于操作系统内核通常会出于安全原因将它们放弃的所有内存归零,足够聪明的calloc可能只返回内存,而不进行额外的归零。同样,如果你只是分配一些你知道很小的东西,那么在性能方面使用malloc+memset可能会更好。