Handy C Snippet

| | Comments (5)

While doing some refactoring, I noticed a distinct pattern which I've seen frequently in other people's code (not just REALbasic related). Quite often, I'd see code like this:

someType *buffer = (someType *)malloc( 4 * sizeof( someType ) );
memset( buffer, 0, 4 * sizeof( someType ) );

The purpose of the code is to allocate a buffer large enough to hold four items of someType. Then the newly allocated data is zeroed out. You'll see this coming from C an awful lot because it's the easiest way to make a dynamically-sized array. Since you've allocated enough space for four someType items, you can access them as buffer[ 0 ] thru buffer[ 3 ].

However, there's a better way to do this using a slightly different API: calloc. The calloc API was made for exactly this coding paradigm -- it allocates room for X items of Y size and it initializes the memory to zero.

someType *buffer = (someType *)calloc( 4, sizeof( someType ) );

Not only is this code more concise and easier to read, it's also slightly more efficient (in my tests).

So next time you find yourself writing some C code where you're doing a malloc followed by a memset to zero, you should consider just using calloc instead.

5 Comments

Interesting... Is this different from just making an array like:

int x[4];

I can't remember if that zeros out data... I dont' remember much of my C.

And you just noticed this? :-)

@jdiwnab -- Yes, it is different. That won't zero out the data (you'd have to say = { 0 }; to to do that). But what's more, C doesn't have a dynamic array concept, so you have to do it by hand using memory allocation. So if I knew it was 4 items, I'd just use 4. But if I don't know how many items, I can use a variable instead.

@Seth -- I've always known that (this has been a coding habit of mine for many years). But plenty of people don't use calloc, which is why I pointed it out.

Aaron, thanks for this pointer. I always avoided calloc(), because I somehow mixed it up with alloca(). Your posting reminded me I wanted to check that out. It's odd what things you just don't do if you're in a hurry and don't want to put up with new, unfamiliar stuff...

Oh, and BTW: I think C99 introduced the ability to do the equivalent of alloca() by writing code like:

int x[myVar];

to get a variably-sized array on the stack.

@Uli -- Well, alloca allocates the data on the stack, whereas malloc/calloc allocates the data on the heap. So there's a pretty extensive difference between those, which does point out a difference between using malloc and type var[ size ]; My code allocates on the heap, and the declarative version allocates on the stack. Generally speaking, this isn't going to be a problem. However, there are implications to it.

Leave a comment

Disclaimer

I'm currently an employee of REAL Software. My blog is mine. The opinions represented in this blog are mine as well and may not represent my employer's opinions. All original material is copyrighted and property of the author.

REALbasic® is a registered trademark of REAL Software, Inc. REAL SQL Server™ and Lingua™ are pending trademarks of REAL Software, Inc. All rights reserved.