C, I can be taught! At least about calloc.

A long, long time ago, I learned about malloc() in C. I could make a buffer like this:

char *buffer = malloc (1024);

…use it, then release it when I was done like this:

free (buffer);

I have discussed malloc here in the past, including a recent post about an error checking malloc I created to find a memory leak.

But today, the Bing CoPilot A.I. suggested I use calloc instead.

And I wasn’t even sure I even remembered this was a thing. And it has been there since before C was standardized…

void* calloc (size_t num, size_t size);

malloc() will return a block of memory and, depending on the operating system and implementation in the compiler, that memory may have old data in it. Hackers were known to write programs that would allocate blocks of memory then inspect it to see what they could find left over from another program previously using it.

Hey, everybody’s gotta have a hobby…

calloc() is a “clear allocation” where it will initialize the memory it returns to zero before returning it to you. It also takes two parameters instead of just one. While malloc() wants to know the number of bytes you wish to reserve, calloc() wants to how know many things (bytes, structures, etc.) you want to reserve, and the size of each thing.

To allocate 1024 bytes using calloc() you would use:

char *buffer = calloc (1, 1024);

…and get one thing of 1024 bytes. Or maybe you prefer reversing that:

char *buffer = calloc (1024, 1);

…so you get 1024 things that are 1 byte each.

Either way, what you get back is memory all set to zeros.

calloc() was suggested by the A.I. because I was allocating a set of structures like this:

// Typedefs
typedef struct
{
    int x;
    int y;
    int color;
} MyStruct;

MyStruct *array = malloc (sizeof(MyStruct) * 42);

The A.I. saw that, and suggested calloc() instead, like this:

MyStruct *array = calloc (42, sizeof(MyStruct));

I do think that looks a bit cleaner and more obvious, if you are familiar with calloc(), and as long as you don’t need the extra speed (setting that memory to 0 should take more time than not doing that), it seems like something to consider.

And maybe that will break me (and other programmers who wrote code before me that I may one day maintain) from doing it manually like…

char *ptr = malloc (1024);
memset (ptr, 0x0, 1024);

I wonder if I will even remember this the next time I need to malloc() something.

I mean calloc() something.

Whatever.

Until then…

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.