13-Data Structures in C Programming
C Programming Lessons, Learn C Programming, Introduction to C Language, How to Program with C
This section introduces dynamic data structures that can grow and shrink in size at runtime.
struct node{
int data;
struct node *newPtr;
};
newPtr can be used to connect a ‘struct node‘ type structure to another structure of the same type. Self-referential structures can be linked together to form useful data types such as lists, queues, stacks, and trees.
There are 4 library functions provided by C defined under <stdlib.h> header file to facilitate dynamic memory allocation in C programming. They are:
- malloc()
- calloc()
- free()
- realloc()
With the malloc, free functions, the sizeof operator is required for dynamic memory allocation.
The malloc function takes the number of bytes to be allocated as an argument and returns a void* type pointer to the allocated space.
newPtr = malloc(sizeof(struct node))
This statement calculates the size of the structure of type “struct node” in bytes, allocates a new memory space of “sizeof(struct node)” bytes, and stores a pointer to the space allocated to the newPtr variable.
free(newPtr) expression is used to free dynamically allocated memory space with the previous call to malloc.
Example Malloc
#include <stdio.h>
#include <stdlib.h>
int main()
{
// This pointer will hold the
// base address of the block created
int * newPtr;
int n, i;
// Get the number of elements for the array
printf("Enter number of elements:");
scanf("%d",&n);
printf("Entered number of elements: %d\n", n);
// Dynamically allocate memory using malloc()
newPtr = (int*)malloc(n * sizeof(int));
// Check if the memory has been successfully
// allocated by malloc or not
if (newPtr == NULL)
{
printf("\nMemory not allocated.\n");
exit(0);
}
else
{
// Memory has been successfully allocated
printf("Memory successfully allocated using malloc.\n");
// Get the elements of the array
for (i = 0; i < n; ++i)
{
newPtr[i] = i + 1;
}
// Print the elements of the array
printf("\nThe elements of the array are: ");
for (i = 0; i < n; ++i)
{
printf("%d, ", newPtr[i]);
}
}
return 0;
}

Example Calloc
The name “calloc” stands for contiguous allocation.
The malloc() function allocates memory and leaves the memory uninitialized.
The calloc() function allocates memory and initializes all bits to zero.
#include <stdio.h>
#include <stdlib.h>
int main()
{
// This pointer will hold the
// base address of the block created
int* newPtr;
int n, i;
// Get the number of elements for the array
printf("Enter number of elements: \n");
scanf("%d",&n);
// Dynamically allocate memory using calloc()
newPtr = (int*)calloc(n, sizeof(int));
// Check if the memory has been successfully
// allocated by calloc or not
if (newPtr == NULL)
{
printf("Memory not allocated.\n");
exit(0);
}
else
{
// Memory has been successfully allocated
printf("Memory successfully allocated using calloc.\n");
// Get the elements of the array
for (i = 0; i < n; ++i)
{
newPtr[i] = i + 1;
}
// Print the elements of the array
printf("The elements of the array are: ");
for (i = 0; i < n; ++i)
{
printf("%d, ", newPtr[i]);
}
}
return 0;
}

Example Free()
Dynamically allocated memory created with calloc() or malloc() does not free itself.
free() is used to free the space.
#include <stdio.h>
#include <stdlib.h>
int main()
{
// This pointer will hold the
// base address of the block created
int *newPtr, *ptr1;
int n, i;
// Get the number of elements for the array
printf("Enter number of elements: \n");
scanf("%d",&n);
// Dynamically allocate memory using malloc()
newPtr = (int*)malloc(n * sizeof(int));
// Dynamically allocate memory using calloc()
ptr1 = (int*)calloc(n, sizeof(int));
// Check if the memory has been successfully
// allocated by malloc or not
if (newPtr == NULL || ptr1 == NULL)
{
printf("Memory not allocated.\n");
exit(0);
}
else
{ // Memory has been successfully allocated
printf("Memory successfully allocated using malloc.\n");
// Free the memory
free(newPtr);
printf("Malloc Memory successfully freed.\n");
// Memory has been successfully allocated
printf("\nMemory successfully allocated using calloc.\n");
// Free the memory
free(ptr1);
printf("Calloc Memory successfully freed.\n");
}
return 0;
}

Example Realloc()
If the dynamically allocated memory is insufficient or more than required, realloc() function can change the previously allocated memory size.
#include <stdio.h>
#include <stdlib.h>
int main()
{
// This pointer will hold the
// base address of the block created
int *newPtr;
int n, i;
// Get the number of elements for the array
n = 3;
printf("Enter number of elements: %d\n", n);
// Dynamically allocate memory using calloc()
newPtr = (int*)calloc(n, sizeof(int));
// Check if the memory has been successfully
// allocated by malloc or not
if (newPtr == NULL)
{
printf("Memory not allocated.\n");
exit(0);
}
else
{ // Memory has been successfully allocated
printf("Memory successfully allocated using calloc.\n");
// Get the elements of the array
for (i = 0; i < n; ++i) {
newPtr[i] = i + 1;
}
// Print the elements of the array
printf("The elements of the array are: ");
for (i = 0; i < n; ++i)
{
printf("%d, ", newPtr[i]);
}
// Get the new size for the array
printf("\n\nEnter the new size of the array: \n");
scanf("%d",&n);
// Dynamically re-allocate memory using realloc()
newPtr = realloc(newPtr, n * sizeof(int));
// Memory has been successfully allocated
printf("Memory successfully re-allocated using realloc.\n");
// Get the new elements of the array
for (i = 3; i < n; ++i)
{
newPtr[i] = i + 1;
}
// Print the elements of the array
printf("The elements of the array are: ");
for (i = 0; i < n; ++i)
{
printf("%d, ", newPtr[i]);
}
free(newPtr);
}
return 0;
}

