Memory Management in C
This chapter will explain dynamic memory management in C. The C language provides several functions for memory allocation and management, which can be found in the <stdlib.h> header file.
No. | Function and Description |
---|---|
1 | void *calloc(int num, int size); <br>Dynamically allocates a contiguous block of memory for num objects, each of size size , and initializes all bytes to 0. The result is a memory block of num*size bytes, with each byte set to 0. |
2 | void free(void *address); <br>Frees the memory block pointed to by address , which is a memory space dynamically allocated. |
3 | void *malloc(int num); <br>Allocates a block of memory of specified size in the heap to store data. This memory block is not initialized after allocation, and its values are unknown. |
4 | void *realloc(void *address, int newsize); <br>Reallocates memory, expanding it to newsize . |
Note: The void *
type represents a pointer of an unspecified type. In C and C++, a void *
type can be type-casted to any other pointer type.
Dynamic Memory Allocation
When programming, if you know the size of the array in advance, it is easier to define the array. For example, an array to store a person's name, which can hold up to 100 characters, can be defined as follows:
char name[100];
However, if you do not know the length of the text to be stored in advance, such as a detailed description of a topic, you need to define a pointer that points to a character of undefined memory size and allocate memory as needed, as shown below:
Example
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char name[100];
char *description;
strcpy(name, "Zara Ali");
/* Dynamically allocate memory */
description = (char *)malloc(200 * sizeof(char));
if (description == NULL)
{
fprintf(stderr, "Error - unable to allocate required memory\n");
}
else
{
strcpy(description, "Zara Ali is a DPS student in class 10th");
}
printf("Name = %s\n", name);
printf("Description: %s\n", description);
}
When the above code is compiled and executed, it produces the following result:
Name = Zara Ali
Description: Zara Ali is a DPS student in class 10th
The above program can also be written using calloc(), simply by replacing malloc with calloc, as shown below:
calloc(200, sizeof(char));
When dynamically allocating memory, you have full control and can pass any size value. Arrays that are predefined with a fixed size cannot change their size once defined.
Resizing and Freeing Memory
When the program exits, the operating system automatically releases all memory allocated to the program. However, it is recommended to call the free() function to release memory when it is no longer needed.
Alternatively, you can increase or decrease the size of an allocated memory block by calling the realloc() function. Let's look at the above example again using realloc() and free():
Example
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char name[100];
char *description;
strcpy(name, "Zara Ali");
/* Dynamically allocate memory */
description = (char *)malloc(30 * sizeof(char));
if (description == NULL)
{
fprintf(stderr, "Error - unable to allocate required memory\n");
}
else
{
strcpy(description, "Zara Ali is a DPS student.");
}
/* Suppose you want to store a larger description */
description = (char *)realloc(description, 100 * sizeof(char));
if (description == NULL)
{
fprintf(stderr, "Error - unable to allocate required memory\n");
}
else
{
strcat(description, " She is in class 10th");
}
printf("Name = %s\n", name);
printf("Description: %s\n", description);
/* Free the memory using free() function */
free(description);
}
When the above code is compiled and executed, it produces the following result:
Name = Zara Ali
Description: Zara Ali is a DPS student. She is in class 10th
You can try not reallocating additional memory, and the strcat() function will produce an error due to insufficient memory available for storing the description.