Memory, storage classes and printf in C
How malloc and free work, what static and extern change, and how printf format specifiers read their arguments.
The second set of C topics deals with how long data lives and how it is displayed. Questions here test storage classes, dynamic memory and printf formats, and the bugs that come from getting them wrong.
Storage classes
- auto is the default for local variables. They are created on each call and disappear when the function returns.
- static inside a function means the variable is initialised once and keeps its value between calls.
- static at file level means the global variable or function is visible only in that source file.
- extern declares a variable that is defined in another file, without creating a new one.
void visit(void) {
static int count = 0;
count++;
printf("%d ", count);
}
/* calling visit() three times prints: 1 2 3 */
malloc and free
malloc(n) reserves n bytes on the heap and returns a pointer, or NULL if it fails. The memory is not initialised; use calloc if you need it zeroed. Every successful allocation should be released exactly once with free.
int *nums = malloc(5 * sizeof(int));
if (nums == NULL) {
return 1;
}
for (int i = 0; i < 5; i++) nums[i] = i * i;
free(nums);
nums = NULL;
Common mistakes are forgetting to check for NULL, freeing the same pointer twice, using memory after freeing it, and losing the only pointer to a block, which causes a memory leak. Setting the pointer to NULL after free makes accidental reuse easier to catch.
printf format specifiers
%dfor int,%ufor unsigned int,%ldfor long.%ffor double, with%.2fshowing two decimal places.%cfor a character and%sfor a string.%xfor hexadecimal,%ofor octal and%pfor a pointer.%zufor size_t values, such as the result of sizeof.
A mismatched specifier, such as printing a double with %d, is undefined behaviour and often prints nonsense. Also remember that integer division drops the fraction: 7 / 2 is 3, while 7 / 2.0 is 3.5.
Checklist
For every malloc, ask three questions: did I check for NULL, where is the matching free, and could anything use the pointer after that free?
More in Programming