Unit 5
Dynamic Memory Allocation in C using malloc(), calloc(), free() and realloc()
Since C is a structured language, it has some fixed rules for programming.
One of them includes changing the size of an array. An array is a collection
of items stored at contiguous memory locations.
As can be seen, the length (size) of the array above is 9. But what if there is
a requirement to change this length (size)? For example,
If there is a situation where only 5 elements are needed to be entered in
this array. In this case, the remaining 4 indices are just wasting memory
in this array. So there is a requirement to lessen the length (size) of the
array from 9 to 5.
This procedure is referred to as Dynamic Memory Allocation in C.
Therefore, C Dynamic Memory Allocation can be defined as a procedure in
which the size of a data structure (like Array) is changed during the runtime.
C provides some functions to achieve these tasks. There are 4 library
functions provided by C defined under <stdlib.h> header file to facilitate
dynamic memory allocation in C programming. They are:
1. malloc()
2. calloc()
3. free()
4. realloc()
Let’s look at each of them in greater detail.
C malloc() method
The “malloc” or “memory allocation” method in C is used to dynamically allocate a
single large block of memory with the specified size. It returns a pointer of type void
which can be cast into a pointer of any form. It doesn’t Initialize memory at execution
time so that it has initialized each block with the default garbage value initially.
Syntax of malloc() in C
ptr = (cast-type*) malloc(byte-size)
For Example:
ptr = (int*) malloc(100 * sizeof(int));
Since the size of int is 4 bytes, this statement will allocate 400 bytes of memory. And,
the pointer ptr holds the address of the first byte in the allocated memory.
If space is insufficient, allocation fails and returns a NULL pointer.
Example of malloc() in C
#include <stdio.h>
#include <stdlib.h>
int main()
{
// This pointer will hold the
// base address of the block created
int* ptr;
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()
ptr = (int*)malloc(n * sizeof(int));
// Check if the memory has been
successfully
// allocated by malloc or not
if (ptr == NULL) {
printf("Memory 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) {
ptr[i] = i + 1;
}
// Print the elements of the
array
printf("The elements of the
array are: ");
for (i = 0; i < n; ++i) {
printf("%d, ", ptr[i]);
}
}
return 0;
}
Output
Enter number of elements: 5
Memory successfully allocated using malloc.
The elements of the array are: 1, 2, 3, 4, 5,
C calloc() method
1. “calloc” or “contiguous allocation” method in C is used to dynamically allocate the
specified number of blocks of memory of the specified type. it is very much similar
to malloc() but has two different points and these are:
2. It initializes each block with a default value ‘0’.
3. It has two parameters or arguments as compare to malloc().
Syntax of calloc() in C
ptr = (cast-type*)calloc(n, element-size);
here, n is the no. of elements and element-size is the size of
each element.
For Example:
ptr = (float*) calloc(25, sizeof(float));
This statement allocates contiguous space in memory for 25 elements each with the
size of the float.
If space is insufficient, allocation fails and returns a NULL pointer.
Example of calloc() in C
#include <stdio.h>
#include <stdlib.h>
int main()
{
// This pointer will hold the
// base address of the block created
int* ptr;
int n, i;
// Get the number of elements for
the array
n = 5;
printf("Enter number of elements:
%d\n", n);
// Dynamically allocate memory
using calloc()
ptr = (int*)calloc(n, sizeof(int));
// Check if the memory has been
successfully
// allocated by calloc or not
if (ptr == 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) {
ptr[i] = i + 1;
}
// Print the elements of the
array
printf("The elements of the
array are: ");
for (i = 0; i < n; ++i) {
printf("%d, ", ptr[i]);
}
}
return 0;
}
Output
Enter number of elements: 5
Memory successfully allocated using calloc.
The elements of the array are: 1, 2, 3, 4, 5,
C free() method
“free” method in C is used to dynamically de-allocate the memory. The memory
allocated using functions malloc() and calloc() is not de-allocated on their own. Hence
the free() method is used, whenever the dynamic memory allocation takes place. It
helps to reduce wastage of memory by freeing it.
Syntax of free() in C
free(ptr);
Example of free() in C
#include <stdio.h>
#include <stdlib.h>
int main()
{
// This pointer will hold the
// base address of the block created
int *ptr, *ptr1;
int n, i;
// Get the number of elements for
the array
n = 5;
printf("Enter number of elements:
%d\n", n);
// Dynamically allocate memory
using malloc()
ptr = (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 (ptr == 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(ptr);
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;
}
Output
Enter number of elements: 5
Memory successfully allocated using malloc.
Malloc Memory successfully freed.
Memory successfully allocated using calloc.
Calloc Memory successfully freed.
C realloc() method
“realloc” or “re-allocation” method in C is used to dynamically change the memory
allocation of a previously allocated memory. In other words, if the memory previously
allocated with the help of malloc or calloc is insufficient, realloc can be used
to dynamically re-allocate memory. re-allocation of memory maintains the already
present value and new blocks will be initialized with the default garbage value.
Syntax of realloc() in C
ptr = realloc(ptr, newSize);
where ptr is reallocated with new size 'newSize'.
If space is insufficient, allocation fails and returns a NULL pointer.
Example of realloc() in C
#include <stdio.h>
#include <stdlib.h>
int main()
{
// This pointer will hold the
// base address of the block created
int* ptr;
int n, i;
// Get the number of elements for
the array
n = 5;
printf("Enter number of elements:
%d\n", n);
// Dynamically allocate memory
using calloc()
ptr = (int*)calloc(n, sizeof(int));
// Check if the memory has been
successfully
// allocated by malloc or not
if (ptr == 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) {
ptr[i] = i + 1;
}
// Print the elements of the
array
printf("The elements of the
array are: ");
for (i = 0; i < n; ++i) {
printf("%d, ", ptr[i]);
}
// Get the new size for the
array
n = 10;
printf("\n\nEnter the new size
of the array: %d\n", n);
// Dynamically re-allocate
memory using realloc()
ptr = (int*)realloc(ptr, 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 = 5; i < n; ++i) {
ptr[i] = i + 1;
}
// Print the elements of the
array
printf("The elements of the
array are: ");
for (i = 0; i < n; ++i) {
printf("%d, ", ptr[i]);
}
free(ptr);
}
return 0;
}
Output
Enter number of elements: 5
Memory successfully allocated using calloc.
The elements of the array are: 1, 2, 3, 4, 5,
Enter the new size of the array: 10
Memory successfully re-allocated using realloc.
The elements of the array are: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
C Structures
The structure in C is a user-defined data type that can be used to group
items of possibly different types into a single type. The struct keyword is
used to define the structure in the C programming language. The items in
the structure are called its member and they can be of any valid data type.
C Structure Declaration
We have to declare structure in C before using it in our program. In structure
declaration, we specify its member variables along with their datatype. We
can use the struct keyword to declare the structure in C using the following
syntax:
Syntax
struct structure_name {
data_type member_name1;
data_type member_name1;
....
....
};
The above syntax is also called a structure template or structure prototype
and no memory is allocated to the structure in the declaration.
C Structure Definition
To use structure in our program, we have to define its instance. We can do
that by creating variables of the structure type. We can define structure
variables using two methods:
Structure Variable Declaration with Structure Template
struct structure_name {
data_type member_name1;
data_type member_name1;
....
....
}variable1, varaible2, ...;
2. Structure Variable Declaration after Structure Template
// structure declared beforehand
struct structure_name variable1, variable2, .......;
Access Structure Members
We can access structure members by using the ( . ) dot operator.
Syntax
structure_name.member1;
strcuture_name.member2;
In the case where we have a pointer to the structure, we can also use the arrow
operator to access the members.
Initialize Structure Members
Structure members cannot be initialized with the declaration. For example, the
following C program fails in the compilation.
struct Point
{
int x = 0; // COMPILER ERROR: cannot initialize members
here
int y = 0; // COMPILER ERROR: cannot initialize members
here
};
The reason for the above error is simple. When a datatype is declared, no memory is
allocated for it. Memory is allocated only when variables are created.
We can initialize structure members in 3 ways which are as follows:
1. Using Assignment Operator.
2. Using Initializer List.
3. Using Designated Initializer List.
1. Initialization using Assignment Operator
struct structure_name str;
str.member1 = value1;
str.member2 = value2;
str.member3 = value3;
.
.
.
2. Initialization using Initializer List
struct structure_name str = { value1, value2, value3 };
In this type of initialization, the values are assigned in sequential order as they are
declared in the structure template.
3. Initialization using Designated Initializer List
Designated Initialization allows structure members to be initialized in any order. This
feature has been added in the C99 standard.
struct structure_name str = { .member1 = value1, .member2 =
value2, .member3 = value3 };
The Designated Initialization is only supported in C but not in C++.
Example of Structure in C
The following C program shows how to use structures
// C program to illustrate the use of
structures
#include <stdio.h>
// declaring structure with name str1
struct str1 {
int i;
char c;
float f;
char s[30];
};
// declaring structure with name str2
struct str2 {
int ii;
char cc;
float ff;
} var; // variable declaration with
structure template
// Driver code
int main()
{
// variable declaration after
structure template
// initialization with initializer
list and designated
// initializer list
struct str1 var1 = { 1, 'A', 1.00,
"GeeksforGeeks" },
var2;
struct str2 var3 = { .ff = 5.00, .ii
= 5, .cc = 'a' };
// copying structure using
assignment operator
var2 = var1;
printf("Struct 1:\n\ti = %d, c =
%c, f = %f, s = %s\n",
var1.i, var1.c, var1.f,
var1.s);
printf("Struct 2:\n\ti = %d, c = %c,
f = %f, s = %s\n",
var2.i, var2.c, var2.f,
var2.s);
printf("Struct 3\n\ti = %d, c = %c,
f = %f\n", var3.ii,
var3.cc, var3.ff);
return 0;
}
Output
Struct 1:
i = 1, c = A, f = 1.000000, s = GeeksforGeeks
Struct 2:
i = 1, c = A, f = 1.000000, s = GeeksforGeeks
Struct 3
i = 5, c = a, f = 5.000000
Nested Structures
C language allows us to insert one structure into another as a member. This process
is called nesting and such structures are called nested structures. There are two
ways in which we can nest one structure into another:
1. Embedded Structure Nesting
In this method, the structure being nested is also declared inside the parent structure.
Example
struct parent {
int member1;
struct member_str member2 {
int member_str1;
char member_str2;
...
}
...
}
2. Separate Structure Nesting
In this method, two structures are declared separately and then the member structure
is nested inside the parent structure.
Example
struct member_str {
int member_str1;
char member_str2;
...
}
struct parent {
int member1;
struct member_str member2;
...
}
One thing to note here is that the declaration of the structure should always be
present before its definition as a structure member. For example, the declaration
below is invalid as the struct mem is not defined when it is declared inside the parent
structure.
struct parent {
struct mem a;
};
struct mem {
int var;
};
Accessing Nested Members
We can access nested Members by using the same ( . ) dot operator two times as
shown:
str_parent.str_child.member;
Example of Structure Nesting
// C Program to illustrate structure
nesting along with
// forward declaration
#include <stdio.h>
// child structure declaration
struct child {
int x;
char c;
};
// parent structure declaration
struct parent {
int a;
struct child b;
};
// driver code
int main()
{
struct parent var1 = { 25, 195, 'A'
};
// accessing and printing nested
members
printf("var1.a = %d\n", var1.a);
printf("var1.b.x = %d\n", var1.b.x);
printf("var1.b.c = %c", var1.b.c);
return 0;
}
Output
var1.a = 25
var1.b.x = 195
var1.b.c = A
Structure Pointer in C
We can define a pointer that points to the structure like any other variable. Such
pointers are generally called Structure Pointers. We can access the members of the
structure pointed by the structure pointer using the ( -> ) arrow operator.
Example of Structure Pointer in C
// C program to illustrate the structure
pointer
#include <stdio.h>
// structure declaration
struct Point {
int x, y;
};
int main()
{
struct Point str = { 1, 2 };
// p2 is a pointer to structure p1
struct Point* ptr = &str;
// Accessing structure members
using structure pointer
printf("%d %d", ptr->x, ptr->y);
return 0;
}
Output
1 2
Array of Structures in C
When dealing with a large set of related data and different data types, organizing and
managing it efficiently is crucial. In C programming, the combination of arrays and
structures i.e. array of structures provides a powerful tool for managing that. In this
article, we discuss the concept of an Array of Structures in C.
What is Array?
The array is a homogeneous collection of elements stored in the continuous memory
location. The size of the array is fixed and we can randomly access the elements
using their index.
Declaration of Array
array_type array_name[size];
What is Structure?
The structure is one of the user-defined data types in C that can contain elements of
different types as its members.
Declaration of a Structure in C
struct structure_name{
memberType memberName;
...
...
};
Array of Structures
An array whose elements are of type structure is called array of structure. It is
generally useful when we need multiple structure variables in our program.
Need for Array of Structures
Suppose we have 50 employees and we need to store the data of 50 employees. So
for that, we need to define 50 variables of struct Employee type and store the data
within that. However, declaring and handling the 50 variables is not an easy task.
Let’s imagine a bigger scenario, like 1000 employees.
So, if we declare the variable this way, it’s not possible to handle this.
struct Employee emp1, emp2, emp3, .. . ... . .. ... emp1000;
For that, we can define an array whose data type will be struct Employee soo that will
be easily manageable.
Declaration of Array of Structures
struct structure_name array_name [number_of_elements];
Initialization of Array of Structures
We can initialize the array of structures in the following ways:
struct structure_name array_name [number_of_elements] = {
{element1_value1, element1_value2, ....},
{element2_value1, element2_value2, ....},
......
......
};
The same initialization can also be done as:
struct structure_name array_name [number_of_elements] = {
element1_value1, element1_value2 ....,
element2_value1, element2_value2 .....
};
GNU C compilers supports designated initialization for structures so we can also use
this in the initialization of an array of structures.
struct structure_name array_name [number_of_elements] = {
{.element3 = value, .element1 = value, ....},
{.element2 = value, .elementN = value, ....},
......
......
};
Example of Array of Structure in C
// C program to demonstrate the array of
structures
#include <stdio.h>
// structure template
struct Employee {
char Name[20];
int employeeID;
int WeekAttendence[7];
};
// driver code
int main()
{
// defining array of structure of
type Employee
struct Employee emp[5];
// adding data
for (int i = 0; i < 5; i++) {
emp[i].employeeID = i;
strcpy(emp[i].Name, "Amit");
int week;
for (week = 0; week < 7; week++)
{
int attendence;
emp[i].WeekAttendence[week]
= week;
}
}
printf("\n");
// printing data
for (int i = 0; i < 5; i++) {
printf("Emplyee ID: %d -
Employee Name: %s\n",
emp[i].employeeID,
emp[i].Name);
printf("Attendence\n");
int week;
for (week = 0; week < 7; week++)
{
printf("%d ",
emp[i].WeekAttendence[week]);
}
printf("\n");
}
return 0;
}
Output
Emplyee ID: 0 - Employee Name: Amit
Attendence
0 1 2 3 4 5 6
Emplyee ID: 1 - Employee Name: Amit
Attendence
0 1 2 3 4 5 6
Emplyee ID: 2 - Employee Name: Amit
Attendence
0 1 2 3 4 5 6
Emplyee ID: 3 - Employee Name: Amit
Attendence
0 1 2 3 4 5 6
Emplyee ID: 4 - Employee Name: Amit
Attendence
0 1 2 3 4 5 6
Structure and functions in C :make the code efficient. A code that consumes
less memory and takes less time to execute is good.
Structure functions in C make the code efficient. A code that consumes less
memory and takes less time to execute is good.
Structures are one such user-defined data type. The structures can have many fundamental data
types known as structure members grouped into a single user-defined data type.
Functions are the blocks of codes that perform a specific task when called. We need to pass the
parameters to the function, and the function returns the result. Structures can also be passed as
parameters to the functions.
When a function is called, if we pass the values of the variables to the function, it is known as
the call by value. Instead of passing the values, if we pass the address of the variables to the
function, it is known as call by reference.
The dot (.) operator is used to access a structure member. The arrow (->) operator is to access the
members of a structure when the pointer references the structure.
With these basics of structures and functions, It will be easy to understand structure functions
clearly.
Structure-function can be effectively used while writing code. Structures can be passed as
arguments to the functions. This can be done in three ways. They are,
Passing the members of the structures as an argument.
Passing the entire structure as an argument.
Passing the address of the structure as arguments.
How to Pass Structure Members To Functions?
Sometimes we don’t want to pass the entire structure to the function. We want to pass only a few
members of the structure. We can use the dot (.) operator to access the individual members of the
structure and pass them to the function.
Let us create a structure to hold the details of a student, such as the name of the student, roll
number, and marks, and print out just the roll number and marks using a function. Passing the
entire structure to the function is unnecessary when we want to print only a few structure
members.
In the above example, the structure contains the name of the student as well, but we need to print
only the percentage and roll number. Therefore we pass only the required structure members to
function.
Let us look at the code and understand how to pass structure members to the function.
#include <stdio.h>
struct student {
char name[50];
int per,rno;
};
void display(int a, int b);
int main() {
struct student s1;
printf("Enter name: ");
gets(s1.name);
printf("Enter the roll number: ");
scanf("%d",&s1.rno);
printf("Enter percentage: ");
scanf("%d", &s1.per);
display(s1.rno,s1.per);
return 0;
}
void display(int a, int b ) {
printf("\nDisplaying information\n");
printf("Roll number: %d", a);
printf("\nPercentage: %d", b);
}
In the above code, we created a structure to hold the name, roll number, and percentage of the
student. The input from the user is stored in the structure. A function named display() is created,
which takes the roll number and the percentage of the student as the parameter. Using the dot
(.) operator, we accessed the member of the structure and passed it to the function.
The output of the above code is as follows:
Enter name: Gourav
Enter the roll number: 42
Enter percentage: 98
Displaying information
Roll number: 42
Percentage: 98
In this way, we can pass structure members to a function.
Unions in C:
The Union is a user-defined data type in C language that can contain
elements of the different data types just like structure. But unlike structures,
all the members in the C union are stored in the same memory location. Due
to this, only one member can store data at the given instance.
Syntax of Union in C
The syntax of the union in C can be divided into three steps which are as
follows:
C Union Declaration
In this part, we only declare the template of the union, i.e., we only declare
the members’ names and data types along with the name of the union. No
memory is allocated to the union in the declaration.
union union_name {
datatype member1;
datatype member2;
...
};
Keep in mind that we have to always end the union declaration with a semi-
colon.
Different Ways to Define a Union Variable
We need to define a variable of the union type to start using union members. There
are two methods using which we can define a union variable.
1. With Union Declaration
2. After Union Declaration
1. Defining Union Variable with Declaration
union union_name {
datatype member1;
datatype member2;
...
} var1, var2, ...;
2. Defining Union Variable after Declaration
union union_name var1, var2, var3...;
where union_name is the name of an already declared union.
Access Union Members
We can access the members of a union by using the ( . ) dot operator just like
structures.
var1.member1;
where var1 is the union variable and member1 is the member of the union.
The above method of accessing the members of the union also works for the nested
unions.
var1.member1.memberA;
Here,
var1 is a union variable.
member1 is a member of the union.
memberA is a member of member1.
Initialization of Union in C
The initialization of a union is the initialization of its members by simply assigning the
value to it.
var1.member1 = some_value;
One important thing to note here is that only one member can contain some value at
a given instance of time.
Example of Union
// C Program to demonstrate how to use
union
#include <stdio.h>
// union template or declaration
union un {
int member1;
char member2;
float member3;
};
// driver code
int main()
{
// defining a union variable
union un var1;
// initializing the union member
var1.member1 = 15;
printf("The value stored in member1
= %d",
var1.member1);
return 0;
}
Output
The value stored in member1 = 15
Difference between C Structure and C Union:
The following table lists the key difference between the structure and union in C: