C Dynamic Memory Allocation
Stack vs Heap
C programs use two memory regions for variables:
| Feature | Stack | Heap |
|---|---|---|
| Allocation | Automatic (on function call) | Manual (malloc/calloc/realloc) |
| Deallocation | Automatic (on function return) | Manual (free) |
| Size | Fixed, limited (~1“8 MB) | Large (limited by RAM) |
| Speed | Fast | Slower (OS involvement) |
| Use case | Local variables, function calls | Large/variable-size data, long-lived data |
Dynamic Memory Functions
All dynamic memory functions are in <stdlib.h>:
| Function | Description | Initialization |
|---|---|---|
malloc(size) | Allocates size bytes | Uninitialized (garbage values) |
calloc(n, size) | Allocates n × size bytes | Zero-initialized |
realloc(ptr, size) | Resizes previously allocated block | Preserves existing data |
free(ptr) | Releases allocated memory | — |
#include <stdio.h>
#include <stdlib.h>
int main() {
int n;
printf("Enter number of elements: ");
scanf("%d", &n);
// malloc — allocate n integers (uninitialized)
int *arr = (int*)malloc(n * sizeof(int));
if (arr == NULL) {
printf("Memory allocation failed!\n");
return 1;
}
// Fill array
for (int i = 0; i < n; i++) {
arr[i] = (i + 1) * 10;
}
// Print array
printf("Array: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
// ALWAYS free when done
free(arr);
arr = NULL; // good practice: avoid dangling pointer
printf("Memory freed.\n");
return 0;
}
/*
Enter number of elements: 5
Array: 10 20 30 40 50
Memory freed.
*/
#include <stdio.h>
#include <stdlib.h>
int main() {
// calloc — allocates and zero-initializes
int *arr = (int*)calloc(5, sizeof(int));
if (!arr) { printf("calloc failed\n"); return 1; }
printf("calloc (all zeros): ");
for (int i = 0; i < 5; i++) printf("%d ", arr[i]); // 0 0 0 0 0
printf("\n");
// Fill with values
for (int i = 0; i < 5; i++) arr[i] = i + 1;
// realloc — resize to 10 elements
int *bigger = (int*)realloc(arr, 10 * sizeof(int));
if (!bigger) {
printf("realloc failed\n");
free(arr);
return 1;
}
arr = bigger; // arr now points to the resized block
// Initialize new elements
for (int i = 5; i < 10; i++) arr[i] = (i + 1) * 10;
printf("After realloc (10 elements): ");
for (int i = 0; i < 10; i++) printf("%d ", arr[i]);
printf("\n");
free(arr);
return 0;
}
/*
calloc (all zeros): 0 0 0 0 0
After realloc (10 elements): 1 2 3 4 5 60 70 80 90 100
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[50];
int score;
} Student;
int main() {
int n;
printf("How many students? ");
scanf("%d", &n);
// Allocate array of structs dynamically
Student *students = (Student*)malloc(n * sizeof(Student));
if (!students) { printf("Allocation failed\n"); return 1; }
// Input data
for (int i = 0; i < n; i++) {
printf("Enter name and score for student %d: ", i + 1);
scanf("%s %d", students[i].name, &students[i].score);
}
// Find highest scorer
int maxIdx = 0;
for (int i = 1; i < n; i++) {
if (students[i].score > students[maxIdx].score) maxIdx = i;
}
printf("\nAll students:\n");
for (int i = 0; i < n; i++) {
printf(" %-15s %d\n", students[i].name, students[i].score);
}
printf("Top scorer: %s (%d)\n", students[maxIdx].name, students[maxIdx].score);
free(students);
students = NULL;
return 0;
}
Ready to Level Up Your Skills?
Explore 500+ free tutorials across 20+ languages and frameworks.