Allocate storage when the required size is known at runtime
Dynamic allocation gives storage whose lifetime you control. It is useful when an input determines an array's size or when data must outlive the function that creates it. Each allocation needs an owner responsible for releasing it exactly once.
Checked allocation and cleanup
#include
#include
#include
int main(void) {
size_t count = 3;
int *values = NULL;
if (count > SIZE_MAX / sizeof *values) {
return 1;
}
values = malloc(count * sizeof *values);
if (values == NULL) {
fputs("Allocation failed\n", stderr);
return 1;
}
for (size_t i = 0; i < count; ++i) {
values[i] = (int)i + 1;
}
printf("sum=%d\n", values[0] + values[1] + values[2]);
free(values);
values = NULL;
return 0;
} Expected output: sum=6. Multiplication is checked before allocation. sizeof *values ties the element size to the pointer type. In C, malloc's void-pointer result does not require a cast; include stdlib.h so the correct declaration is visible.
malloc, calloc and realloc
malloc does not initialize the allocated bytes. calloc requests an element count and size and initializes the storage to all-bits-zero; do not generalize that bit pattern to every possible pointer or floating representation. realloc may resize in place or move the allocation. Newly added storage is not initialized.
size_t new_count = 6;
if (new_count <= SIZE_MAX / sizeof *values) {
int *replacement = realloc(values, new_count * sizeof *values);
if (replacement != NULL) {
values = replacement;
} else {
/* The original allocation is still owned by values. */
}
}This fragment belongs before free in a program that owns values. Never assign realloc directly to the only pointer to the allocation: on failure you would lose the original address. After success, do not use old aliases to the previous allocation. Handle a requested size of zero separately instead of relying on version-dependent zero-size realloc behavior.
Memory errors to prevent
- A leak occurs when owned storage is no longer reachable but was never released.
- A double free releases the same allocation twice.
- A use-after-free accesses storage after release.
- An overflow writes past the requested bounds.
Practice
Allocate five ints, initialize them to 10, 20, 30, 40 and 50, then compute 150 and free the storage. Add an allocation-failure branch. Finally, resize the array using a temporary pointer and initialize only the newly added elements. Trace ownership on every return path.