Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is there no "recalloc" in the C standard?

Everyone knows that:

  • realloc resizes an existing block of memory or copies it to a larger block.
  • calloc ensures the memory is zeroed out and guards against arithmetic overflows and is generally geared toward large arrays.

Why doesn't the C standard provide a function like the following that combines both of the above?

void *recalloc(void *ptr, size_t num, size_t size);

Wouldn't it be useful for resizing huge hash tables or custom memory pools?

like image 920
Matt Avatar asked Feb 12 '15 20:02

Matt


2 Answers

Generally in C, the point of the standard library is not to provide a rich set of cool functions. It is to provide an essential set of building blocks, from which you can build your own cool functions.

Your proposal for recalloc would be trivial to write, and therefore is not something the standard lib should provide.

Other languages take a different approach: C# and Java have super-rich libraries that make even complicated tasks trivial. But they come with enormous overhead. C has minimal overhead, and that aids in making it portable to all kinds of embedded devices.

like image 62
abelenky Avatar answered Oct 24 '22 10:10

abelenky


I assume you're interested in only zeroing out the new part of the array:

Not every memory allocator knows how much memory you're using in an array. for example, if I do:

char* foo = malloc(1);

foo now points to at least a chunk of memory 1 byte large. But most allocators will allocate much more than 1 byte (for example, 8, to keep alignment).

This can happen with other allocations, too. The memory allocator will allocate at least as much memory as you request, though often just a little bit more.

And it's this "just a little bit more" part that screws things up (in addition to other factors that make this hard). Because we don't know if it's useful memory or not. If it's just padding, and you recalloc it, and the allocator doesn't zero it, then you now have "new" memory that has some nonzeros in it.

For example, what if I recalloc foo to get it to point to a new buffer that's at least 2 bytes large. Will that extra byte be zeroed? Or not? It should be, but note that the original allocation gave us 8 bytes, so are reallocation doesn't allocate any new memory. As far as the allocator can see, it doesn't need to zero any memory (because there's no "new" memory to zero). Which could lead to a serious bug in our code.

like image 35
Cornstalks Avatar answered Oct 24 '22 10:10

Cornstalks