MODULE 4 -Storage Classes, Structure and Union, Pointers
Storage classes – The scope, visibility and lifetime of variables. Auto,Extern, Static and Register
storage classes. Storage classes in a single source file and multiple source files
Structure and Union - Defining, giving values to members, initialization and comparison of
structure variables, arrays of structure, arrays within structures, structures within structures,
structures and functions, unions
Pointers definition, declaring and initializing pointers, accessing a variable through address and
through pointer, pointer expressions, pointer increments and scale factor
Pointers and arrays, pointers and functions, pointers and structure
Dynamic memory allocation and memory management functions
Storage classes
Storage classes define the scope, visibility, and lifetime of variables and
functions. They determine where and how long a variable or function can be
accessed and how its memory is managed. The four main storage classes in C are:
auto
register
static
extern
1. auto
Scope: Local (only within the block where the variable is declared).
Visibility: Visible only within the block or function where it is declared.
Lifetime: Exists during the execution of the block or function, and is
automatically destroyed when the block or function ends.
Description:
o The auto storage class is the default for local variables.
o These variables are automatically created when the function is called
and destroyed when the function exits.
o They are not initialized by default, meaning they contain garbage
values unless explicitly initialized.
Example:
void function() {
auto int x = 10; // 'auto' is optional, as it
is the default for local variables
printf("%d", x);
}
2. extern
Scope: Global (accessible across multiple files, if declared correctly).
Visibility: Visible to all functions and files that declare the variable with
extern.
Lifetime: The variable exists for the duration of the program.
Description:
o The extern keyword is used to declare a global variable or function
that is defined in another file.
o It does not allocate memory for the variable but links it to an existing
global variable declared in another file.
o extern is useful when working with multiple source files.
Example:
// File1.c
int x = 10; // Definition of x
// File2.c
extern int x; // Declaration of x from File1.c
void function() {
printf("%d", x); // Accesses the global
variable x from File1.c
}
3. static
Scope: Limited to the file or function where the variable is declared.
Visibility: The variable is not visible outside the block or file in which it is
declared.
Lifetime: The variable exists throughout the lifetime of the program.
Description:
o When used with local variables, static ensures the variable retains
its value between function calls. It is initialized only once and
maintains its state across function calls.
o When used with global variables or functions, static restricts the
visibility of the variable or function to the file it is declared in
(internal linkage).
Example:
void function() {
static int count = 0; // Retains value between
function calls
count++;
printf("%d", count); // Prints count each time
the function is called
}
// File1.c
static int x = 10; // x is visible only in File1.c
// File2.c
// Cannot access x because it is static in File1.c
4. register
Scope: Local (only within the block where the variable is declared).
Visibility: Visible only within the block or function where it is declared.
Lifetime: Exists during the execution of the block or function.
Description:
o The register storage class suggests that the variable be stored in
the CPU registers instead of RAM for faster access.
o This is a suggestion to the compiler; it is not guaranteed that the
variable will be stored in a register.
o register variables cannot be accessed by the address operator (&)
because they may not have a memory address.
Example:
void function() {
register int i; // Suggests to the compiler to
store i in a register
for(i = 0; i < 10; i++) {
printf("%d", i);
}
}
Summary of Differences:
Storage
Scope Visibility Lifetime Memory Allocation
Class
Local to Automatic, on
Local to the Stack, automatically
auto the function
function/block allocated/deallocated
function entry/exit
Throughout
Visible across Global, linked across
extern Global program
files files
execution
Throughout
Local or Limited to the Retained for program's
static program
Global function/file duration
execution
Local to Automatic, on
Local to the Suggests faster access via
register the function
function/block CPU registers
function entry/exit
Each storage class has its specific use cases, and understanding them helps in
writing efficient and clear programs in C.
Storage classes in a single source file and multiple source files
In C programming, storage classes define the scope (visibility) and lifetime of
variables and functions. There are four primary storage classes in C: auto ,
register,static and extern
Let's break down their usage in the context of single source file and multiple
source files:
1. Single Source File
In a single source file, all variables and functions are contained within that one file.
The storage class directly affects their scope and lifetime.
Example: Single Source File
#include <stdio.h>
void function1() {
auto int x = 5; // auto is default, can be
omitted
static int y = 10; // static variable
printf("x = %d, y = %d\n", x, y);
x++;
y++;
}
int main() {
function1(); // First call, x=5, y=10
function1(); // Second call, x=5, y=11 (x resets,
y doesn't)
return 0;
}
auto: Local variables are the default with auto storage class, and their value
is lost between function calls.
static: Static variables preserve their values between function calls.
2. Multiple Source Files
In multiple source files, storage classes like extern and static help in sharing
or isolating variables and functions between the files.
Example: Multiple Source Files
Let's split the program into two files.
file1.c:
#include <stdio.h>
extern int x; // Declare x, defined in another file
static int y = 20; // y is local to file1.c
void function1() {
printf("x = %d, y = %d\n", x, y);
}
file2.c:
#include <stdio.h>
int x = 10; // x is defined here and accessible to
other files
int main() {
function1(); // Access the x from file1.c
return 0;
}
Compilation: To compile multiple source files, you need to link them together:
gcc file1.c file2.c -o program
./program
extern: extern is used in file1.c to declare the variable x that is defined in
file2.c. This allows the variable x to be accessed across source files.
static: static in file1.c ensures that y is only accessible within that file,
and cannot be accessed by other files.
These storage classes help in controlling data visibility and lifetime, whether you're
working with a single source file or multiple source files in C.
Structure
structure 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 a structure.
The items in the structure are called its member and they can be of any valid data
type.
Example:
#include <stdio.h>
// Defining a structure
struct A {
int x;
};
int main() {
// Creating a structure variable
struct A a;
// Initializing member
a.x = 11;
printf("%d", a.x);
return 0;
}
Output
11
Explanation: In this example, a structure A is defined to hold an integer member
x. A variable a of type struct A is created and its member x is initialized to 11 by
accessing it using dot operator. The value of a.x is then printed to the console.
Structures are used when you want to store a collection of different data types,
such as integers, floats, or even other structures under a single name.
Syntax of Structure
There are two steps of creating a structure in C:
1. Structure Definition
2. Creating Structure Variables
Structure Definition
A structure is defined using the struct keyword followed by the structure name and
its members. It is also called a structure template or structure prototype, and no
memory is allocated to the structure in the declaration.
struct structure_name {
data_type1 member1;
data_type2 member2;
…
};
structure_name: Name of the structure.
member1, member2, …: Name of the members.
data_type1, data_type2, …: Type of the members.
Be careful not to forget the semicolon at the end.
Creating Structure Variable
After structure definition, we have to create variable of that structure to use it. It is
similar to the any other type of variable declaration:
struct strcuture_name var;
We can also declare structure variables with structure definition.
struct structure_name {
…
}var1, var2….;
Basic Operations of Structure
Following are the basic operations commonly used on structures:
1. Access Structure Members
To access or modify members of a structure, we use the ( . ) dot operator. This is
applicable when we are using structure variables directly.
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.
structure_ptr -> member1
structure_ptr -> member2
2. Initialize Structure Members
Structure members cannot be initialized with the declaration. For example, the
following C program fails in the compilation.
struct structure_name {
data_type1 member1 = value1; // COMPILER ERROR: cannot initialize members
here
data_type2 member2 = value2; // 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. So there is
no space to store the value assigned.
We can initialize structure members in 4 ways which are as follows:
Default Initialization
By default, structure members are not automatically initialized to 0 or NULL.
Uninitialized structure members will contain garbage values. However, when a
structure variable is declared with an initializer, all members not explicitly
initialized are zero-initialized.
struct structure_name = {0}; // Both x and y are initialized to 0
Initialization using Assignment Operator
struct structure_name str;
str.member1 = value1;
….
Note: We cannot initialize the arrays or strings using assignment operator after
variable declaration.
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.
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++.
#include <stdio.h>
// Defining a structure to represent a student
struct Student {
char name[50];
int age;
float grade;
};
int main() {
// Declaring and initializing a structure
// variable
struct Student s1 = {"Rahul",20, 18.5};
// Designated Initializing another stucture
struct Student s2 = {.age = 18, .name =
"Vikas", .grade = 22};
// Accessing structure members
printf("%s\t%d\t%.2f\n", [Link], [Link],
[Link]);
printf("%s\t%d\t%.2f\n", [Link], [Link],
[Link]);
return 0;
}
Output
Rahul 20 18.50
Vikas 18 22.00
3. Copy Structure
Copying structure is simple as copying any other variables. For example, s1 is
copied into s2 using assignment operator.
s2 = s1;
But this method only creates a shallow copy of s1 i.e. if the structure s1 have some
dynamic resources allocated by malloc, and it contains pointer to that resource,
then only the pointer will be copied to s2. If the dynamic resource is also needed,
then it has to be copied manually (deep copy).
#include <stdio.h>
#include <stdlib.h>
struct Student {
int id;
char grade;
};
int main() {
struct Student s1 = {1, 'A'};
// Create a copy of student s1
struct Student s1c = s1;
printf("Student 1 ID: %d\n", [Link]);
printf("Student 1 Grade: %c", [Link]);
return 0;
}
Output
Student 1 ID: 1
Student 1 Grade: A
4. Passing Structure to Functions
Structure can be passed to a function in the same way as normal variables. Though,
it is recommended to pass it as a pointer to avoid copying a large amount of data.
#include <stdio.h>
// Structure definition
struct A {
int x;
};
// Function to increment values
void increment(struct A a, struct A* b) {
a.x++;
b->x++;
}
int main() {
struct A a = { 10 };
struct A b = { 10 };
// Passing a by value and b by pointer
increment(a, &b);
printf("a.x: %d \tb.x: %d", a.x, b.x);
return 0;
}
Output
a.x: 10 b.x: 11
In C programming, structures are user-defined data types that allow you to group
different types of data together. These can be used in various ways, such as arrays
of structures, arrays within structures, and structures within structures. Let's break
each of these down with examples:
Arrays of Structures
An array of structures is a collection of multiple structures of the same type, where
each structure can store different values.
Example:
#include <stdio.h>
struct Student {
char name[50];
int age;
float grade;
};
int main() {
struct Student students[3]; // Array of 3
structures
// Assign values to the first student
strcpy(students[0].name, "Alice");
students[0].age = 20;
students[0].grade = 90.5;
// Assign values to the second student
strcpy(students[1].name, "Bob");
students[1].age = 22;
students[1].grade = 85.0;
// Assign values to the third student
strcpy(students[2].name, "Charlie");
students[2].age = 21;
students[2].grade = 88.0;
// Print student details
for (int i = 0; i < 3; i++) {
printf("Student %d: %s, Age: %d, Grade:
%.2f\n", i+1, students[i].name, students[i].age,
students[i].grade);
}
return 0;
}
In this example, students is an array of Student structures. Each structure has
a name, age, and grade.
Arrays within Structures
You can define an array inside a structure to store multiple values of the same type.
Example:
#include <stdio.h>
struct Student {
char name[50];
int grades[5]; // Array to hold 5 grades
};
int main() {
struct Student student1;
// Assign values
strcpy([Link], "Alice");
[Link][0] = 85;
[Link][1] = 90;
[Link][2] = 78;
[Link][3] = 92;
[Link][4] = 88;
// Print student's grades
printf("Student Name: %s\n", [Link]);
for (int i = 0; i < 5; i++) {
printf("Grade %d: %d\n", i+1,
[Link][i]);
}
return 0;
}
Here, the Student structure has an array grades[] of 5 integers, where we
store multiple grades for each student.
Structures within Structures
A structure can also contain another structure as a member. This allows you to
build more complex data types by nesting structures.
Example:
#include <stdio.h>
struct Address {
char street[100];
char city[50];
char state[50];
int zipCode;
};
struct Person {
char name[50];
int age;
struct Address address; // Structure within a
structure
};
int main() {
struct Person person1;
// Assign values
strcpy([Link], "John Doe");
[Link] = 30;
strcpy([Link], "123 Elm St");
strcpy([Link], "Somewhere");
strcpy([Link], "CA");
[Link] = 90210;
// Print person's details
printf("Name: %s\n", [Link]);
printf("Age: %d\n", [Link]);
printf("Address: %s, %s, %s, %d\n",
[Link], [Link],
[Link], [Link]);
return 0;
}
In this example, the Person structure contains another structure Address as a
member. This allows a person to have an address, which is itself a structure.
Summary:
Arrays of structures: Useful for storing multiple records of the same type.
Arrays within structures: Useful for storing multiple values of the same
type inside a single structure.
Structures within structures: Allows creating more complex data types by
nesting structures inside each other.
These concepts are fundamental for working with more complex data in C
programming.
Unions
union is a user-defined data type 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 point in time.
Syntax of Union in C
The syntax of union can be defined into two parts:
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 name {
type1 member1;
type2 member2;
.
.
};
Create 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:
Creating Union Variable with Declaration
union name{
type member1;
type member2;
…
} var1, var2, …;
Creating Union Variable after Declaration
union name var1, var2, var3…;
where 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.
Initialize Union
The initialization of a union is the initialization of its members by simply assigning
the value to it.
var1.member1 = val;
One important thing to note here is that only one member can contain some
value at a given instance of time.
Size of Union
The size of the union will always be equal to the size of the largest member of the
union. All the less-sized elements can store the data in the same space without any
overflow. Let’s take a look at the code example:
#include <stdio.h>
// Declaring multiple unions
union A{
int x;
char y;
};
union B{
int arr[10];
char y;
};
int main() {
// Finding size using sizeof() operator
printf("Sizeof A: %ld\n", sizeof(union A));
printf("Sizeof B: %ld\n", sizeof(union B));
return 0;
}
Output
Sizeof A: 4
Sizeof B: 40
The above unions’ memory can be visualized as shown:
Nested Union
In C, we can define a union inside another structure or union. This is called nested
union and is commonly used when you want to efficiently organize and access
related data while sharing memory among its members.
Syntax
struct/union … {
mem1…
union name {
type1 member1
type2 member2
.
.
}nested_member_name;
};
Parameter Structure Union
A structure is a user-defined A union is a user-defined data type
Definition data type that groups different that allows storing different data
data types into a single entity. types at the same memory location.
The keyword struct is used to The keyword union is used to define
Keyword
define a structure a union
The size is the sum of the sizes The size is equal to the size of the
of all members, with padding if largest member, with possible
Size
necessary. padding.
Each member within a structure
Memory Memory allocated is shared by
is allocated unique storage area
Allocation individual members of union.
of location.
No data overlap as members are Full data overlap as members shares
Data Overlap
independent. the same memory.
Accessing Individual member can be Only one member can be accessed at
Members accessed at a time. a time.
Pointers
In C programming, pointers are variables that store the memory address of another variable.
Here's a detailed explanation of pointers, declaring, initializing them, and the associated
concepts:
1. Pointers Definition
A pointer is a variable that holds the address of another variable. It is
used to indirectly access or modify the value of that variable.
2. Declaring and Initializing Pointers
A. Pointer Declaration
To declare a pointer, we use the (*) dereference operator before its
name. In pointer declaration, we only declare the pointer but do not
initialize it.
int *p; // Pointer to an integer
float *f; // Pointer to a float
char *c; // Pointer to a character
B. Pointer Initialization
Pointer initialization is the process where we assign some initial value to
the pointer variable. We use the (&) addressof operator to get the
memory address of a variable and then store it in the pointer variable.
Note: We can also declare and initialize the pointer in a single step. This
is called pointer definition.
int x = 10;
int *p = &x; // p now holds the address of x
C. Pointer Dereferencing
Dereferencing a pointer is the process of accessing the value stored in
the memory address specified in the pointer. We use the same (*)
dereferencing operator that we used in the pointer declaration.
Note: It is recommended that the pointers should always be initialized to
some value before starting using it. Otherwise, it may lead to number of
errors.
3. Accessing a Variable Through Address and Through Pointer
Accessing a Variable Through Address: The address of a
variable can be obtained using the address-of operator (&).
int x = 10;
printf("Address of x: %p\n", &x); // &x
gives the memory address of x
Accessing a Variable Through Pointer: You can access the value
of a variable through a pointer using the dereference operator (*),
which gives you the value stored at the address the pointer holds.
int x = 10;
int *p = &x; // p points to x
printf("Value of x through pointer: %d\n",
*p); // Dereferencing p gives the value of
x
4. Pointer Expressions
Pointer expressions are arithmetic operations that can be performed on
pointers.
Pointer Arithmetic: You can perform arithmetic on pointers like
addition, subtraction, and comparison. When you add or subtract
an integer from a pointer, it moves the pointer by that number of
elements (not bytes).
int arr[5] = {1, 2, 3, 4, 5};
int *p = arr; // p points to arr[0]
printf("Value at p: %d\n", *p); // Access
first element of arr
p++; // Move pointer to next element
printf("Value at p after increment: %d\n",
*p); // Access second element of arr
Pointer arithmetic rules:
o p + n: Moves the pointer p by n elements (not bytes).
o p - n: Moves the pointer p back by n elements.
o p++ or ++p: Increments the pointer to point to the next
element.
o p-- or --p: Decrements the pointer to point to the
previous element.
5. Pointer Increments and Scale Factor
Pointer Increments: When you increment or decrement a pointer,
it doesn't just move by one byte. Instead, it moves by the size of
the type it points to. This is the scale factor.
int arr[] = {10, 20, 30};
int *p = arr; // p points to arr[0]
p++; // p now points to arr[1] (the second
element)
printf("Value at p: %d\n", *p); // Prints
20
o If p is a pointer to int, p++ increases the pointer by
sizeof(int). For example, if sizeof(int) is 4 bytes,
p++ moves the pointer by 4 bytes.
Scale Factor: The scale factor is the size of the data type the
pointer points to. It determines how much the pointer will be
incremented or decremented in memory.
For example:
o If int *p, then each increment moves p by
sizeof(int) bytes (typically 4 bytes on most systems).
o If char *p, each increment moves p by sizeof(char)
bytes (1 byte).
Example Code
#include <stdio.h>
int main() {
int x = 10;
int *p = &x;
// Accessing variable through pointer
printf("Value of x through pointer: %d\n",
*p);
// Pointer arithmetic
int arr[] = {1, 2, 3, 4, 5};
p = arr; // p points to arr[0]
printf("First element: %d\n", *p);
p++; // Move to next element
printf("Second element: %d\n", *p);
// Pointer increment and scale factor
p += 2; // Move two positions ahead
printf("Fourth element: %d\n", *p);
return 0;
}
In C programming, pointers are variables that store the memory address of another variable.
Understanding how pointers interact with arrays, functions, and structures is key to mastering C.
Let’s break down each concept:
1. Pointers and Arrays
In C, an array is essentially a collection of elements stored in contiguous
memory locations. Pointers and arrays are closely related. Here's how:
Array and Pointer Relationship:
The name of an array is a pointer to its first element.
You can use a pointer to traverse an array.
Array indexing and pointer arithmetic are similar.
#include <stdio.h>
int main() {
int arr[] = {1, 2, 3, 4, 5};
int *ptr = arr; // Points to the first
element of the array
printf("First element: %d\n", *ptr); //
Dereferencing the pointer
// Using pointer arithmetic to access
elements
for(int i = 0; i < 5; i++) {
printf("Element %d: %d\n", i, *(ptr +
i)); // ptr + i is the address of arr[i]
}
return 0;
}
Output:
First element: 1
Element 0: 1
Element 1: 2
Element 2: 3
Element 3: 4
Element 4: 5
arr is the base address of the array, which is equivalent to
&arr[0].
ptr points to the first element (arr[0]).
You can use pointer arithmetic (*(ptr + i)) to access each
element of the array.
2. Pointers and Functions
Pointers are useful when you want to pass large structures or arrays to
functions efficiently. Also, pointers allow functions to modify variables
from the caller.
Passing by Reference (using pointers):
When you pass a variable to a function, it’s typically passed by value (a
copy). However, using pointers, you can pass by reference and modify
the original variable.
#include <stdio.h>
void increment(int *p) {
(*p)++; // Dereferencing the pointer to
modify the value
}
int main() {
int num = 10;
printf("Before increment: %d\n", num);
increment(&num); // Pass the address of num
to the function
printf("After increment: %d\n", num);
return 0;
}
Output:
Before increment: 10
After increment: 11
increment takes an int *p parameter, which is a pointer to
an integer.
By passing &num, you pass the address of num to the function.
Inside the function, the pointer is dereferenced ((*p)++) to
modify the original value of num.
Returning Pointers from Functions:
You can also return pointers from functions, but you must be careful
about returning pointers to local variables, as they may go out of scope.
#include <stdio.h>
int* findMax(int *arr, int size) {
int *max = arr;
for(int i = 1; i < size; i++) {
if (*(arr + i) > *max) {
max = arr + i;
}
}
return max; // Return pointer to max
element
}
int main() {
int arr[] = {1, 3, 7, 2, 5};
int *max = findMax(arr, 5);
printf("Maximum value: %d\n", *max); //
Dereference to get the value
return 0;
}
Output:
Maximum value: 7
3. Pointers and Structures
Structures in C are used to group variables of different data types.
Pointers to structures are commonly used to pass structures to functions
or to dynamically allocate memory for structures.
Structure with Pointers:
When using structures with pointers, you can access the structure's
members using the -> operator, which is shorthand for dereferencing
the pointer and accessing the member.
#include <stdio.h>
struct Point {
int x;
int y;
};
int main() {
struct Point p1 = {10, 20};
struct Point *ptr = &p1; // Pointer to the
structure
// Accessing structure members through
pointer
printf("Point x: %d, y: %d\n", ptr->x, ptr-
>y);
return 0;
}
Output:
Point x: 10, y: 20
ptr is a pointer to a struct Point.
The -> operator is used to access the members of the structure
through the pointer.
Passing Structures to Functions using Pointers:
Passing large structures by value can be inefficient. Instead, you can
pass a pointer to a structure to avoid copying.
#include <stdio.h>
struct Person {
char name[30];
int age;
};
void updatePerson(struct Person *p)
{
p->age = 30;
printf(p->name, sizeof(p->name), "John
Doe");
}
int main() {
struct Person person = {"Alice", 25};
printf("Before update: %s, %d\n",
[Link], [Link]);
updatePerson(&person); // Pass pointer to
the structure
printf("After update: %s, %d\n",
[Link], [Link]);
return 0;
}
Output:
Before update: Alice, 25
After update: John Doe, 30
updatePerson takes a pointer to a struct Person.
The structure’s fields can be modified inside the function via the
pointer.
Pointers and Arrays: Arrays are closely related to pointers. You
can use pointers to manipulate arrays and perform pointer
arithmetic to access array elements.
Pointers and Functions: Pointers allow you to pass variables by
reference, enabling functions to modify the actual values of
arguments. They also allow returning large data structures
efficiently.
Pointers and Structures: Pointers are useful for passing structures
to functions, dynamically allocating memory for structures, and
accessing structure members using the -> operator.
Dynamic Memory Allocation in C
In C, memory is dynamically allocated using functions provided by the
standard library <stdlib.h>. The memory is allocated from the heap,
which is a region of memory used for dynamic memory allocation.
Here are the main memory management functions in C:
1. malloc() (Memory Allocation)
malloc allocates a specified number of bytes of memory on the
heap and returns a pointer to the allocated memory. The memory
is not initialized, meaning it may contain garbage values.
Syntax:
void* malloc(size_t size);
size_t size: Number of bytes to allocate.
Returns a pointer to the allocated memory block if successful, or NULL if the allocation fails.
[Link]() (Contiguous Allocation)
calloc allocates memory for an array of elements and initializes each element to zero.
Syntax:
void* calloc(size_t num, size_t size);
num: Number of elements to allocate.
size: Size of each element.
Returns a pointer to the allocated memory, or NULL if the
allocation fails.
[Link]() (Reallocation)
realloc changes the size of previously allocated memory
(either increasing or decreasing the size). It can also be used to
resize dynamically allocated memory.
void* realloc(void* ptr, size_t size);
ptr: Pointer to the memory block to be resized.
size: New size in bytes for the memory block.
Returns a pointer to the reallocated memory, or NULL if the
allocation fails.
[Link]() (Deallocate Memory)
free is used to release memory that was previously allocated by
malloc, calloc, or realloc. It is important to free
dynamically allocated memory to avoid memory leaks.
void free(void* ptr);
ptr: Pointer to the memory block that needs to be deallocated.