Step 6 of 10
Memory bugs to avoid
Heap memory gives you power and responsibility. C doesn't check any of the following, and none of them reliably crash, which is exactly what makes them dangerous: the program may work in testing and fail later, far from the real mistake.
| Bug | What happens |
|---|---|
| Leak | You lose the last pointer to a block without freeing it. The memory is wasted until the program ends. |
| Use after free | You read or write through a pointer after free. The memory may already hold something else. |
| Double free | You free the same block twice, which corrupts the allocator's bookkeeping. |
| Buffer overflow | You write past the end of a block, silently overwriting neighboring data. Often caused by forgetting the +1 for '\0'. |
Habits that prevent them
- Compute sizes carefully: for strings, length + 1.
- Free temporaries as soon as you're done with them, on every path through the function.
- Set a pointer to
NULLright after freeing it.free(NULL)does nothing, so a second free becomes harmless, and on most systems an accidental use crashes immediately instead of quietly corrupting memory. - Use tools: compile with
-fsanitize=address(AddressSanitizer) or run under Valgrind on your own machine, and they report the exact line.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *label(const char *name, int number) {
size_t n = strlen(name) + 1 + 11 + 1;
char *out = malloc(n);
if (out == NULL) {
return NULL;
}
snprintf(out, n, "%s#%d", name, number);
return out;
}
int main(void) {
char *a = label("player", 42);
if (a == NULL) return 1;
printf("%s\n", a);
free(a);
a = NULL;
free(a);
return 0;
}
player#42
label sizes its buffer for the name, the #, up to 11 characters for the number (an int has at most 10 digits, plus a possible minus sign), and the terminator, and snprintf can never write past n bytes. The second free(a) is harmless because a was set to NULL.
Your turn: this function should build a message but it has two memory bugs (a missing + 1 for the terminator, and a leak of tmp). Fix both so it returns "gg wp" correctly.