区别是什么:
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或反之亦然?
当前回答
还有一个没有提到的区别:大小限制
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()为请求的内存分配多个块
初始化: 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的意思是“连续分配”。
还有一个没有提到的区别:大小限制
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。
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/
在<stdlib.h>标头中声明的calloc()函数比malloc()函数提供了几个优点。
它将内存分配为一定数量的给定大小的元素 它初始化所分配的内存,这样所有的位都是 零。
calloc的一个经常被忽视的优点是,它将帮助保护您免受整数溢出漏洞的侵害。比较:
size_t count = get_int32(file);
struct foo *bar = malloc(count * sizeof *bar);
vs.
size_t count = get_int32(file);
struct foo *bar = calloc(count, sizeof *bar);
如果count大于SIZE_MAX/sizeof *bar,前者可能导致少量分配和后续缓冲区溢出。在这种情况下,后者将自动失败,因为无法创建如此大的对象。
当然,您可能不得不注意不符合规范的实现,这些实现简单地忽略了溢出的可能性……如果在您的目标平台上存在这个问题,那么无论如何都必须对溢出进行手动测试。