CSE115: Programming Language I
Md Shohidul Islam, PhD
Associate Professor
Department of Electrical & Computer Engineering
North South University
Dr. Md Shohidul Islam CSE115 (NSU) Spring 2025 1 / 18
Dynamic Memory Allocation
• In C, memory can be allocated in two main ways:
• Static Memory Allocation: Memory is allocated at compile
time. The size is xed. Examples include global variables and
local variables declared within functions.
• Dynamic Memory Allocation: Memory is allocated at runtime.
The size can be determined and changed during program
execution.
• Dynamic memory allocation is crucial for:
• Creating data structures of variable size (e.g., linked lists, arrays
where the size is not known beforehand).
• E cient memory usage by allocating only the necessary amount
of memory.
Dr. Md Shohidul Islam CSE115 (NSU) Spring 2025 3 / 18
Key Functions for Dynamic Memory Allocation
C provides several standard library functions (de ned in
stdlib.h) for dynamic memory management:
• malloc(): Allocates a block of uninitialized memory of a
speci ed size.
• calloc(): Allocates a block of memory for a speci ed number
of elements of a speci ed size, and initializes all bytes to zero.
• realloc(): Resizes a previously allocated block of memory.
• free(): Deallocates a previously allocated block of memory,
making it available for future use.
Dr. Md Shohidul Islam CSE115 (NSU) Spring 2025 4 / 18
malloc() - Allocating Memory
• malloc() stands for ”memory allocation”.
• Syntax: void* malloc(size t size);
• Takes the size of the memory block to allocate (in bytes) as an
argument.
• Returns a pointer of type void* to the beginning of the
allocated memory block.
• Returns NULL if the allocation fails (e.g., not enough memory
available).
• Does not initialize memory (contains garbage values).
• Important:** You need to cast the returned void* pointer
to the appropriate data type.
Dr. Md Shohidul Islam CSE115 (NSU) Spring 2025 5 / 18
malloc() - Example
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main() {
5 int n;
6 printf("Enter the number of integers: ");
7 scanf("%d", &n);
8
9 int *arr = (int*) malloc(n * sizeof(int)); // Allocate memory for 'n' integers
10
11 if (arr == NULL) { // Check if memory allocation was successful
12 printf("Memory allocation failed!\n");
13 return 1; // Indicate an error
14 }
15
16 printf("Memory allocated successfully.\n");
17
18 for (int i = 0; i < n; i++) { // Use the allocated memory (e.g., store values)
19 arr[i] = i + 1;
20 }
21
22 printf("Elements of the array: ");
23 for (int i = 0; i < n; i++) {
24 printf("%d ", arr[i]);
25 }
26 printf("\n");
27
28 free(arr); // Free the allocated memory when it's no longer needed
29 arr = NULL; // Good practice to set the pointer to NULL after freeing
30
31 return 0;
32 }
33
Dr. Md Shohidul Islam CSE115 (NSU) Spring 2025 6 / 18
malloc() - Another Example
Syntax: ptr = (type *) malloc(size);
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main() {
5 int *ptr;
6 ptr = (int*) malloc(5 * sizeof(int));
7
8 for(int i = 0; i < 5; i++) {
9 ptr[i] = i + 1;
10 printf("%d ", ptr[i]);
11 }
12
13 free(ptr);
14 return 0;}
Output:
1 2 3 4 5
Dr. Md Shohidul Islam CSE115 (NSU) Spring 2025 7 / 18
calloc() - Allocating and Initializing Memory
• calloc() stands for ”contiguous allocation”.
• Syntax: void* calloc(size t num, size t size);
• Takes two arguments:
• num: The number of elements to allocate.
• size: The size of each element (in bytes).
• Allocates a contiguous block of memory su cient to hold an
array of num elements, where each element is size bytes.
• Crucially, it initializes all bytes in the allocated memory to
zero.
• Returns a pointer of type void* to the beginning of the
allocated memory block, or NULL on failure.
Dr. Md Shohidul Islam CSE115 (NSU) Spring 2025 8 / 18
calloc() - Example
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main() {
5 int n;
6 printf("Enter the number of integers: ");
7 scanf("%d", &n);
8
9 // Allocate memory for 'n' integers and initialize to 0
10 int *arr = (int*) calloc(n, sizeof(int));
11
12 if (arr == NULL) { // Check if memory allocation was successful
13 printf("Memory allocation failed!\n");
14 return 1;
15 }
16
17 printf("Memory allocated successfully and initialized to zero.\n");
18
19 printf("Elements of the array: ");
20 for (int i = 0; i < n; i++) {
21 printf("%d ", arr[i]); // Will print all zeros initially
22 }
23 printf("\n");
24
25 arr[0] = 10; // Modify some elements
26 arr[n - 1] = 20; // Modify some elements
27
28 printf("Modified elements: %d and %d\n", arr[0], arr[n - 1]);
29
30 free(arr);
31 arr = NULL;
32 return 0;}
33
Dr. Md Shohidul Islam CSE115 (NSU) Spring 2025 9 / 18
calloc() - Another Example
• Allocates multiple blocks of memory.
• Initializes all elements to zero.
Syntax: ptr = (type *) calloc(n, size);
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main() {
5 int *ptr;
6 ptr = (int*) calloc(5, sizeof(int));
7
8 for(int i = 0; i < 5; i++) {
9 printf("%d ", ptr[i]); // All values are 0
10 }
11
12 free(ptr);
13 return 0;
14 }
15
Dr. Md Shohidul Islam CSE115 (NSU) Spring 2025 10 / 18
realloc() - Resizing Allocated Memory
• realloc() stands for ”re-allocation”.
• It is used to change the size of a previously allocated memory
block.
• Syntax: void* realloc(void* ptr, size t size);
• ptr: A pointer to the memory block previously allocated with
malloc(), calloc(), or realloc(). It can be NULL.
• size: The new size (in bytes) of the memory block.
• Returns a pointer to the newly allocated (and possibly moved)
memory block, or NULL on failure.
• Important Considerations:
• The contents of the original memory block are preserved up to
the smaller of the old and new sizes.
• If realloc() needs to move the memory block to a new
location, the contents are copied to the new location.
• **Always check the return value of realloc() for NULL before
using the returned pointer.**
Dr. Md Shohidul Islam CSE115 (NSU) Spring 2025 11 / 18
realloc() - Example (Increasing Size)
1 int main() {
2 int *arr = (int*) malloc(5 * sizeof(int));
3 if (arr == NULL) {
4 printf("Memory allocation failed!\n");
5 return 1;
6 }
7 printf("Initial memory allocated for 5 integers.\n");
8
9 for (int i = 0; i < 5; i++) { // Fill the initial array
10 arr[i] = i + 1;
11 }
12
13 int *new_arr = (int*) realloc(arr, 10 * sizeof(int)); // Increase the size to 10 integers
14 if (new_arr == NULL) {
15 printf("Memory reallocation failed!\n");
16 free(arr); // Free the original if reallocation fails
17 return 1;
18 }
19 arr = new_arr; // Update the pointer
20
21 printf("Memory reallocated to hold 10 integers.\n");
22
23 for (int i = 5; i < 10; i++) { // Access the new memory
24 arr[i] = (i + 1) * 10;
25 }
26
27 printf("Elements of the resized array: ");
28 for (int i = 0; i < 10; i++) {
29 printf("%d ", arr[i]);
30 }
31
32 free(arr); arr = NULL; return 0;
33 }
34
Dr. Md Shohidul Islam CSE115 (NSU) Spring 2025 12 / 18
realloc() - Another Example (Increasing Size)
Syntax: ptr = realloc(ptr, newSize);
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main() {
5 int *ptr;
6 ptr = (int*) malloc(2 * sizeof(int));
7
8 ptr[0] = 10;
9 ptr[1] = 20;
10
11 ptr = (int*) realloc(ptr, 4 * sizeof(int));
12 ptr[2] = 30;
13 ptr[3] = 40;
14
15 for(int i = 0; i < 4; i++)
16 printf("%d ", ptr[i]);
17
18 free(ptr);
19 return 0;
20 }
Output: 10 20 30 40
Dr. Md Shohidul Islam CSE115 (NSU) Spring 2025 13 / 18
realloc() - Example (Decreasing Size)
• realloc() can also reduce memory size.
• Useful for trimming unused memory.
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main() {
5 int *ptr = (int*) malloc(5 * sizeof(int));
6 if (ptr == NULL) return 1;
7
8 for (int i = 0; i < 5; i++)
9 ptr[i] = (i + 1) * 10;
10
11 // Now reduce size from 5 to 3 integers
12 ptr = (int*) realloc(ptr, 3 * sizeof(int));
13
14 printf("After shrinking:\n");
15 for (int i = 0; i < 3; i++)
16 printf("%d ", ptr[i]);
17
18 free(ptr);
19 return 0;
20 }
21
Dr. Md Shohidul Islam CSE115 (NSU) Spring 2025 14 / 18
free() - Deallocating Memory
• free() is used to release dynamically allocated memory that
is no longer needed.
• Syntax: void free(void* ptr);
• Takes a pointer to a memory block that was previously allocated
using malloc(), calloc(), or realloc().
• After calling free(ptr), the memory block pointed to by ptr is
made available for future allocations.
• Important Rules:**
• You should only free memory that was dynamically allocated.
Freeing statically allocated memory can lead to unde ned
behavior and crashes.
• You should free each allocated block exactly once. Freeing the
same block multiple times can also lead to crashes.
• After freeing a block, it is good practice to set the pointer to
NULL to prevent accidental double freeing or dangling pointer
issues.
Dr. Md Shohidul Islam CSE115 (NSU) Spring 2025 15 / 18
free() - Example (From malloc() example)
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int main() {
5 int *arr = (int*) malloc(5 * sizeof(int));
6 // ... (allocation and usage code as in the malloc
example) ...
7
8 // Free the allocated memory
9 free(arr);
10 arr = NULL; // Good practice
11
12 return 0;
13 }
14
Listing: Freeing dynamically allocated memory
Dr. Md Shohidul Islam CSE115 (NSU) Spring 2025 16 / 18
Summary of Dynamic Memory Allocation
• Dynamic memory allocation allows programs to manage
memory at runtime.
• Key functions: malloc(), calloc(), realloc(), free().
• malloc() allocates uninitialized memory.
• calloc() allocates and initializes memory to zero.
• realloc() resizes allocated memory.
• free() deallocates memory.
• Always check if memory allocation was successful.
• Always call free() after you’re done with dynamic memory.
• Set pointer to NULL after freeing to avoid dangling pointer.
Dr. Md Shohidul Islam CSE115 (NSU) Spring 2025 17 / 18
THE END!
Dr. Md Shohidul Islam CSE115 (NSU) Spring 2025 18 / 18