Memory Management Example in C: Dynamic List Creation
Explore a real-life example of memory management in C programming. Learn how to use dynamic memory allocation to create a flexible, dynamic list that can adjust in size, unlike regular fixed-length arrays.
Memory Management Example in C
Real-Life Memory Management Example
This example demonstrates how to create a program that can manage a dynamic list of any length. Unlike regular arrays in C, which have a fixed length, dynamic memory allows us to create lists that can grow as needed.
Struct Definition
We start by defining a structure for our list:
Struct Definition
struct list {
int *data; // Points to the memory where the list items are stored
int numItems; // Indicates how many items are currently in the list
int size; // Indicates how many items fit in the allocated memory
};
Function to Add Items to the List
The following function adds items to the list:
Function: addToList()
void addToList(struct list *myList, int item) {
// If the list is full then resize the memory to fit 10 more items
if (myList->numItems == myList->size) {
myList->size += 10;
myList->data = realloc(myList->data, myList->size * sizeof(int));
}
// Add the item to the end of the list
myList->data[myList->numItems] = item;
myList->numItems++;
}
Main Function
The main function initializes the list and adds items:
Main Function Example
#include
#include
int main() {
struct list myList;
int amount;
// Create a list and start with enough space for 10 items
myList.numItems = 0;
myList.size = 10;
myList.data = malloc(myList.size * sizeof(int));
// Check if memory allocation was successful
if (myList.data == NULL) {
printf("Memory allocation failed");
return 1; // Exit the program with an error code
}
// Add items to the list
amount = 44;
for (int i = 0; i < amount; i++) {
addToList(&myList, i + 1);
}
// Display the contents of the list
for (int j = 0; j < myList.numItems; j++) {
printf("%d ", myList.data[j]);
}
// Free the memory when it is no longer needed
free(myList.data);
myList.data = NULL;
return 0;
}
Output
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
Understanding the Code
This example consists of three parts:
- A structure named
myList
that holds the data for our list. - The
main()
function that initializes and manages the list. - A function
addToList()
that adds an item to the list.
The myList Structure
The myList
structure contains:
- data: A pointer to the dynamic memory that holds the list contents.
- numItems: Indicates how many items are currently in the list.
- size: Indicates how many items can fit in the allocated memory.
The main() Function
The main()
function initializes the list with space for 10 items:
myList.numItems = 0;
myList.size = 10;
myList.data = malloc(myList.size * sizeof(int));
It checks if the memory allocation was successful:
if (myList.data == NULL) {
printf("Memory allocation failed");
return 1; // Exit the program with an error code
}
If successful, it enters a loop to add items:
for (int i = 0; i < amount; i++) {
addToList(&myList, i + 1);
}
The addToList() Function
The addToList()
function checks if the list is full. If it is, it reallocates memory to fit 10 more items:
if (myList->numItems == myList->size) {
myList->size += 10;
myList->data = realloc(myList->data, myList->size * sizeof(int));
}
Then, it adds the item to the end of the list:
myList->data[myList->numItems] = item;
myList->numItems++;
Why Reserve 10 Items at a Time?
Reserving memory is a balancing act between memory usage and performance. Allocating memory too frequently can be inefficient. By reserving 10 items at a time, we optimize for both memory usage and performance. However, if we know we will need a specific number of items, we can allocate memory accordingly.