Step 1 of 10
Stack vs heap
Every variable you've made so far lives on the stack. The stack is fast and automatic: a function's local variables are created when it's called and destroyed when it returns. But it has two big limits:
- Sizes are fixed when you write the code.
int scores[100]is always 100, even if you only need 3, or need 1,000. (C99 added variable-length arrays whose size is chosen at run time, but they're optional in newer standards and a large one can overflow the stack, which is small: typically 1 to 8 MB.) - Lifetimes are tied to the function. When a function returns, its locals are gone, so it can't create data that outlives it.
The heap removes both limits. It's a large pool of memory you request while the program runs, of any size, and it stays yours until you give it back.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n = 4;
double *temps = malloc(n * sizeof(double));
if (temps == NULL) {
return 1;
}
for (int i = 0; i < n; i++) {
temps[i] = 20.5 + i;
}
printf("%.1f %.1f\n", temps[0], temps[n - 1]);
free(temps);
return 0;
}
20.5 23.5
The pieces
#include <stdlib.h>declaresmallocandfree.malloc(bytes)reserves that many bytes on the heap and returns a pointer to the start. It knows nothing about types, so you compute the size: count xsizeofthe element.malloc(n)alone would be n bytes, not n doubles, a very common bug.- The returned pointer can be used exactly like an array:
temps[i]. mallocreturnsNULLif the memory isn't available. Always check before using it.free(pointer)gives the block back. After that you must not touch it.
The rule of thumb: every successful malloc gets exactly one free. Use the Watch it run link to see the heap block appear, fill, and disappear.
Your turn: allocate room for n ints.