I'm currently writing an embedded application in C where performance is critical.
Currently, I'm allocating lots of empty memory like this: calloc(1, num_bytes)
- however, I simply calculate num_bytes
as the product of a number of items and the size of each item earlier in the code as it's code that used to call malloc
.
calloc
seems unique in that it is the only memory allocation function of the -alloc family which takes two arguments for the size. Is there a good reason for doing this? Are there performance implications for specifying different arguments? What was the rationale in choosing this argument layout?
One advantage of having the separate arguments is that it automatically guards against integer overflow:
// On a 32-bit system, the calloc will almost certainly fail, but the malloc
// will succeed to overflow, likely leading to crashes and/or security holes
// (e.g. if the number of items to allocate came from an untrusted source)
void *a = calloc(64, 67108865); // 2^32/64 + 1
void *b = malloc(64 * 67108865); // will allocate 64 bytes on 32-bit systems
For large allocations, there can also be a performance advantage of doing a calloc
instead of a malloc
and memset
combination, since the calloc
implementation can use its internal knowledge of the heap to avoid unnecessary work or have improved cache performance.
For example, if the allocator decides to use an OS function such as mmap(2)
or VirtualAlloc
to acquire more virtual address space, that memory will come pre-zeroed for security reasons. See this question for a detailed explanation. For small allocations, you're unlikely to notice much of a difference.
Some calloc
implementations just call malloc
and memset
internally, so there's no advantage other than a potential overflow check.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With