C Tutorial
C Memory
malloc allocates. free releases. Every successful malloc needs a matching free.
Most objects need no malloc
A local variable lives until the block ends. The compiler allocates it and frees it. That is automatic storage, often called the stack. Stay here until you have a reason not to: int n, a fixed array, astruct on the stack.
When the size is known only while the program runs, or the object must outlive the current block, you ask the heap. In C that call is malloc. The match is free. Include <stdlib.h>.
malloc allocates, then you check
malloc(sizeof(int)) asks for enough bytes to hold one int and returns a pointer. If the system cannot give you that memory, the pointer is NULL. Check before you write through it.
Example
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *p = malloc(sizeof(int));
if (p == NULL) {
printf("malloc failed\n");
return 1;
}
*p = 7;
printf("%d\n", *p);
free(p);
return 0;
}malloc returns void *. Assigning it to int * is normal in C. The size argument is in bytes: use sizeof instead of a guessed number.
Every successful malloc needs a matching free
Heap memory stays allocated until you free the pointer. Forget free and the program leaks. Free twice and the program is undefined. Free, then leave the pointer alone — do not read *pafter free(p).
Example
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *nums = malloc(3 * sizeof(int));
if (nums == NULL) {
printf("malloc failed\n");
return 1;
}
nums[0] = 3;
nums[1] = 1;
nums[2] = 4;
for (int i = 0; i < 3; i++) {
printf("%d\n", nums[i]);
}
free(nums);
return 0;
}Pair every successful malloc with one free on the same path. If allocation fails, there is nothing to free. Do not return from the function before free unless some other owner will release the pointer.
C has no new and no delete. Those are C++. This track uses malloc andfree from <stdlib.h>.
Who owns the memory
| Storage | You write | Freed by |
|---|---|---|
| Automatic variable | int n = 7; | End of the block |
| Fixed array | int nums[3]; | End of the block |
| Heap object | malloc / free | You, on every path |
Ownership is the question: when this name dies, does the object die with it? A local int answers yes. A pointer from malloc answers no until you free.
A default rule
- Use a local variable or a fixed array when the size is known at compile time.
- Call
mallocwhen the length comes from input or from a calculation at run time. - Check for
NULLbefore you use the pointer. - Call
freeonce, on the same pointer, on every success path.
Run the listings at /c/try. gcc there is C17. That editor is not
Next: sizeof, so the byte count you pass to malloc is the compiler’s, not a guess.
Worked examples
The short listings above are there so you can see the grammar. The programs here use the same statements on quantities that already have units: a speed, a pH, a count of bases. They are classroom numbers. Air resistance is ignored. g is 9.81 m/s² unless a line says otherwise.
Open them in the C editor at /c/try. Change one measurement and check whether the result still has the right unit.
Biology
n sample masses on the heap
You often do not know the sample count when you compile. malloc asks for n doubles at run time. 12, 24, 16, 1 g might be carbon-12, magnesium, oxygen, hydrogen in a teaching set of relative masses — or just four weighings. The program does not care.
If malloc returns NULL, stop. If it succeeds, free the block. Leaking a four-double array once is invisible; doing it in a loop for a week is not.
Example
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n = 4;
double *mass = malloc((size_t)n * sizeof(double));
if (mass == NULL) {
return 1;
}
mass[0] = 12.0;
mass[1] = 24.0;
mass[2] = 16.0;
mass[3] = 1.0;
printf("first sample = %.1f g\n", mass[0]);
free(mass);
return 0;
}Physics
Three voltages, then the series sum
Cells in series add. 1.5 + 3.0 + 4.5 V is 9.0 V. The heap is optional for three numbers; it is the pattern you need when the count comes from a file.
new/delete is C++. In C the pair is malloc and free.
V_series = V1 + V2 + V3
Example
#include <stdio.h>
#include <stdlib.h>
int main(void) {
double *v = malloc(3 * sizeof(double));
if (!v) {
return 1;
}
v[0] = 1.5;
v[1] = 3.0;
v[2] = 4.5;
printf("series total = %.1f V\n", v[0] + v[1] + v[2]);
free(v);
return 0;
}