Dynamic Memory Allocation
- We don’t always know amount of memory needed to store a variable
- We can’t just allocate the memory beforehand
- Instead, we use
malloc()to dynamically allocate memory at runtimemalloc()asks OS for memory on the heap- You should always check if
malloc()failed
- Heap memory survives after a function returns
- Persists until we
free()the memory
- Persists until we
int *nums = malloc(10 * sizeof(int));- Allocates space for 10 integers
- Returns pointer to the first element
- Memory lives until we
free()it
To free memory:
int *vector = randomints(1000);
// use vector...
free(vector); // give memory backString duplication example:
char *my_strdup2(char *str) {
char *new = malloc(strlen(str) + 1); // +1 for '\0'
if (new != NULL) {
strcpy(new, str);
}
return new;
}- Allocates exactly enough memory
- Safe to return pointer as heap memory survives after function returns
Stack and Heap
Stack automatic, temporary memory
- Stores local variables and function call info
- Very fast to allocate/free
- Managed by compiler / OS
Heap region of memory for dynamically allocation memory
- Big pool of memory that program can request from
- Flexible, but slower and higher risk of leaks and corruption
- e.g. forgetting to
free()old memory or writing past allocated memory
- e.g. forgetting to
Stack vs Heap (Analogy)
Imagine memory as a desk:
- Stack: like a neat pile of papers. You put a paper (function call) on top, work on it, then remove it when done. Very structured.
- Heap: like a drawer full of sticky notes. You can ask the OS for any amount of space, at any time, but you must remember where you put it and clean up after yourself.
Clearing Memory
- You can clear memory in the heap using
calloc()calloc(n, size)= allocate and zero-initialize
int *arr = calloc(10, sizeof(int)); // 10 ints, start at 0Reallocating Memory
- You can resize memory allocated by
mallocorcallocusingrealloc()- Remember, this only works for dynamically allocated memory!
- Instead of freeing and allocating again (which would cause you to lose your data),
realloctries to:- Grow/shrink the existing block if possible
- If it can’t, it allocates a new block big enough, copies your old data there, then frees the old one automatically
int *arr = malloc(5 * sizeof(int)); // space for 5 ints
// later we need 10 ints
arr = realloc(arr, 10 * sizeof(int));
if (arr == NULL) {
printf("Reallocation failed!\n");
exit(1);
}