Simplifying Memory Allocation in C using Macros

Saturday, November 19, 2011

This is a tip showing a clever little use-case for macros in C. How many times have you typed

char *s = (char *) malloc(x*sizeof(char));

in C and not thought about it twice? Think: that statement violates a fundamental principle of programming: the DRY (Don’t Repeat Yourself) principle – that too twice over – by repeating the data type char 3 times. If you had to change the data type of s, you’d have to change it in 3 places. Surely that’s something a machine should take care of, not a human. Using C macros we can get that redundancy count down to 2 times, in the process getting a sweet abstraction out for simple memory allocation.

The macro is as follows:

#define ALLOC(t,n) (t *) malloc((n)*sizeof(t))

The effect of this macro is that it allocates memory for n units of data of type t, and returns a pointer to the newly allocated memory. It works by replacing any code of the form ALLOC(t,n) with (t *) malloc((n)*sizeof(t)), where t is any data type and n is any arithmetic expression involving only integers (in a valid use scenario).

A side note on macros: they are blind replace operations, meaning that the replacement occurs exactly as specified. That is why we need the parentheses around n in the replacement text, otherwise ALLOC(int,3+4) would translate to (int *) malloc(3+4*sizeof(int)), but we probably intended (int *) malloc((3+4) * sizeof(int)) (if you’re new to macros in C, you should read a bit about macro functions and macros in general before trying to use them in some critical part of your code, because they can bite back in subtle ways).

So we can replace our initial un-DRY statement with char *s = ALLOC(char,x). Short and sweet, eh?


blog comments powered by Disqus