Dynamic memory allocation in C refers to the process where the program requests memory from the system at runtime, based on its needs, rather than determining the memory size during the compilation phase. This is key to building flexible and scalable programs.
Below, I will comprehensively explain the fundamentals of dynamic memory allocation through concepts, functions, scenarios, examples, and precautions.
1. What is Dynamic Memory Allocation?
In C, there are two ways to allocate memory for variables:
| Allocation Method | Example | Lifecycle |
|---|---|---|
| Static Allocation | <span>int a;</span> |
Released at the end of the function/program |
| Dynamic Allocation | <span>malloc</span>/ <span>free</span> |
Manually allocated and released |
✨ Characteristics of Dynamic Memory:
- Allocated in the heap
- Size allocated at runtime
- More flexible, suitable for handling data structures of uncertain size (such as linked lists, files, user input, etc.)
2. Common Functions (from <span><stdlib.h></span>)
| Function | Description |
|---|---|
<span>malloc</span> |
Allocates a specified number of bytes of memory, uninitialized |
<span>calloc</span> |
Allocates multiple elements, each initialized to 0 |
<span>realloc</span> |
Reallocates the size of existing memory (for expansion or reduction) |
<span>free</span> |
Releases previously allocated memory |
3. Basic Usage Examples
1. <span>malloc</span>
int* arr = (int*)malloc(10 * sizeof(int));
if (arr == NULL) {
// Allocation failed
}
<span>malloc</span>returns<span>void*</span>, requiring a type cast- Does not automatically initialize, memory content is random
2. <span>calloc</span>
int* arr = (int*)calloc(10, sizeof(int)); // Allocate and zero out
- Automatically initializes all elements to
<span>0</span> - More suitable for initializing structures, arrays, etc.
3. <span>realloc</span>
int* arr = (int*)malloc(5 * sizeof(int));
arr = (int*)realloc(arr, 10 * sizeof(int)); // Expand
- Reallocates memory, if the original memory is insufficient, it may move (copy)
4. <span>free</span>
free(arr); // Must free heap memory, otherwise it will cause memory leaks
4. Common Use Cases
✅ 1. User input of an array of uncertain size
int n;
scanf("%d", &n);
int* arr = malloc(n * sizeof(int));
✅ 2. Building dynamic data structures such as linked lists, trees, graphs
typedef struct Node {
int val;
struct Node* next;
} Node;
Node* head = malloc(sizeof(Node));
✅ 3. Loading files/data blocks
When reading files into memory, the size is unknown, requiring dynamic allocation:
char* buffer = malloc(fileSize);
fread(buffer, 1, fileSize, file);
✅ 4. Implementing string concatenation/handling variable-length data
char* str = malloc(20);
strcpy(str, "hello");
str = realloc(str, 40);
strcat(str, " world");
5. Common Errors and Precautions
| Issue | Error Example / Description |
|---|---|
| Forgetting to free memory | Causes memory leaks |
| Double freeing the same memory | <span>free()</span> followed by another <span>free()</span>, undefined behavior |
| Using uninitialized pointers | For example, <span>int* p; *p = 10;</span> is illegal |
<span>realloc</span> does not check return value |
If it fails, it returns <span>NULL</span>, original data may be lost |
| Using freed memory | “Dangling pointer”, <span>use-after-free</span> error |
6. Complete Example: Dynamic Array Input
#include <stdio.h>
#include <stdlib.h>
int main() {
int n;
printf("Enter the number of elements:");
scanf("%d", &n);
int* arr = malloc(n * sizeof(int));
if (!arr) {
printf("Memory allocation failed!\n");
return 1;
}
for (int i = 0; i < n; ++i) {
printf("Please enter number %d:", i + 1);
scanf("%d", &arr[i]);
}
printf("You entered:
");
for (int i = 0; i < n; ++i) {
printf("%d ", arr[i]);
}
free(arr); // Don't forget to free memory
return 0;
}
7. Summary
| Function | Initialized? | Can be used for expansion? | Must be freed? |
|---|---|---|---|
<span>malloc</span> |
❌ Random values | ✅ <span>realloc</span> |
✅ |
<span>calloc</span> |
✅ All zeros | ✅ <span>realloc</span> |
✅ |
<span>realloc</span> |
❌ or ✅ | ✅ | ✅ |