区别是什么:
ptr = malloc(MAXELEMS * sizeof(char *));
And:
ptr = calloc(MAXELEMS, sizeof(char*));
什么时候使用calloc优于malloc或反之亦然?
区别是什么:
ptr = malloc(MAXELEMS * sizeof(char *));
And:
ptr = calloc(MAXELEMS, sizeof(char*));
什么时候使用calloc优于malloc或反之亦然?
当前回答
Calloc()为您提供了一个零初始化的缓冲区,而malloc()则保留未初始化的内存。
对于大的分配,主流操作系统下的大多数calloc实现将从操作系统获得已知的零页(例如通过POSIX mmap(MAP_ANONYMOUS)或Windows VirtualAlloc),因此不需要在用户空间中编写它们。这就是普通malloc从操作系统获取更多页面的方式;calloc只是利用了操作系统的保证。
这意味着calloc内存仍然可以是“干净的”和惰性分配的,写时复制映射到系统范围的共享物理零页。(假设系统有虚拟内存。)例如,在Linux上进行性能实验,效果是显而易见的。
一些编译器甚至可以为你优化malloc + memset(0)为calloc,但如果你想要零内存,最好只在源代码中使用calloc。(或者,如果您试图预先出错以避免以后出现页面错误,那么这种优化将使您的尝试失败。)
如果你不打算在写内存之前读取内存,使用malloc,这样它就可以(潜在地)从内部空闲列表中给你脏内存,而不是从操作系统中获取新页面。(或者不是将空闲列表上的内存块归零以获得少量分配)。
如果没有操作系统,或者它不是一个多用户操作系统,那么calloc的嵌入式实现可能会把它自己的内存设置为0,以阻止进程之间的信息泄漏。
在嵌入式Linux上,malloc可以mmap(MAP_UNINITIALIZED|MAP_ANONYMOUS),这只对一些嵌入式内核启用,因为它在多用户系统上是不安全的。
其他回答
一个不太为人所知的区别是,在具有乐观内存分配的操作系统(如Linux)中,由malloc返回的指针直到程序实际接触它时才得到实际内存的支持。
calloc确实会接触内存(它会在内存上写0),因此您可以确定操作系统正在用实际的RAM(或swap)支持分配。这也是为什么它比malloc慢的原因(它不仅必须将它归零,操作系统还必须通过交换其他进程来找到合适的内存区域)
例如,请参阅这个SO问题以进一步讨论malloc的行为
还有一个没有提到的区别:大小限制
void *malloc(size_t size)只能分配到SIZE_MAX。
Void *calloc(size_t nmemb, size_t size);可以分配大约SIZE_MAX*SIZE_MAX。
在许多具有线性寻址的平台中,不经常使用此功能。这样的系统用nmemb * size <= SIZE_MAX限制calloc()。
考虑一种名为disk_sector的512字节类型,代码希望使用大量扇区。在这里,代码最多只能使用SIZE_MAX/sizeof disk_sector扇区。
size_t count = SIZE_MAX/sizeof disk_sector;
disk_sector *p = malloc(count * sizeof *p);
考虑下面允许更大分配的情况。
size_t count = something_in_the_range(SIZE_MAX/sizeof disk_sector + 1, SIZE_MAX)
disk_sector *p = calloc(count, sizeof *p);
现在,这样一个系统能否提供如此大的分配是另一回事。今天大多数人都不会。然而,当SIZE_MAX为65535时,这种情况已经发生了很多年。根据摩尔定律,这种情况将在2030年左右发生,某些内存模型SIZE_MAX == 4294967295,内存池为100 gb。
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可能会更快。
块数: Malloc()分配请求的单个内存块, Calloc()为请求的内存分配多个块
初始化: Malloc() -不清除和初始化分配的内存。 Calloc() -将分配的内存初始化为0。
速度: Malloc()速度很快。 Calloc()比malloc()慢。
参数和语法: Malloc()接受1个参数:
字节 要分配的字节数
Calloc()有两个参数:
长度 要分配的内存块的数量 字节 在每个内存块上分配的字节数
void *malloc(size_t bytes);
void *calloc(size_t length, size_t bytes);
内存分配方式: malloc函数从可用堆中分配所需“大小”的内存。 calloc函数分配的内存大小等于' num *size '。
名称含义: malloc的意思是“内存分配”。 calloc的意思是“连续分配”。