0% found this document useful (0 votes)
8 views46 pages

Dma

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views46 pages

Dma

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 46

Dynamic Memory Allocation

• C language 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.
• 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.
Why?
• As can be seen, the length (size) of the array 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.
• Take another situation. In this, there is an array of 9 elements
with all 9 indices filled. But there is a need to enter 3 more
elements in this array. In this case, 3 indices more are
required. So the length (size) of the array needs to be changed
from 9 to 12.
• 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()
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.
• #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);
• // 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]);
• }
• }
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.
#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: ");
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);


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");


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.
int main()
{
// Get the elements of the array
// This pointer will hold the for (i = 0; i < n; ++i) {
// base address of the block created ptr[i] = i + 1;
int* ptr; }
int n, i;
// Print the elements of the array
// Get the number of elements for the printf("The elements of the array are: ");
array for (i = 0; i < n; ++i) {
n = 5; printf("%d, ", ptr[i]);
printf("Enter number of elements: %d\n", }
n);
// Get the new size for the array
// Dynamically allocate memory using n = 10;
calloc() printf("\n\nEnter the new size of the array: %d\n",
ptr = (int*)calloc(n, sizeof(int)); n);

// Check if the memory has been // Dynamically re-allocate memory using realloc()
successfully ptr = (int*)realloc(ptr, n * sizeof(int));
// allocated by malloc or not
if (ptr == NULL) {
// Memory has been successfully allocated
printf("Memory not allocated.\n");
printf("Memory successfully re-allocated using
exit(0);
realloc.\n");
}
has been
elsesuccessfully
{ allocated
printf("Memory successfully allocated using calloc.\n");

// Get the elements of the array


for (i = 0; i < n; ++i) {
ptr[i] = i + 1;
}
// 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;
}
• 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,
Linked List

• Linked List is a linear data structure, in which


elements are not stored at a contiguous location, rather
they are linked using pointers. Linked List forms a series
of connected nodes, where each node stores the data
and the address of the next node.

• It is basically chains of nodes, each node contains


information such as data and a pointer to the next
node in the chain. In the linked list there is a head
pointer, which points to the first element of the linked
list, and if the list is empty then it simply points to null
or nothing.
• Node Structure: A node in a linked list typically
consists of two components:
Data: It holds the actual value or data associated with
the node.
Next Pointer: It stores the memory address (reference)
of the next node in the sequence.

Head and Tail: The linked list is accessed through the
head node, which points to the first node in the list. The
last node in the list points to NULL or nullptr, indicating
the end of the list. This node is known as the tail node.
Why linked list data structure
needed?
• Dynamic Data structure: The size of memory can be
allocated or de-allocated at run time based on the operation
insertion or deletion.
• Ease of Insertion/Deletion: The insertion and deletion of
elements are simpler than arrays since no elements need to
be shifted after insertion and deletion, Just the address
needed to be updated.
• Efficient Memory Utilization: As we know Linked List is a
dynamic data structure the size increases or decreases as per
the requirement so this avoids the wastage of memory.
• Implementation: Various advanced data structures can be
implemented using a linked list like a stack, queue, graph,
hash maps, etc.
Types of linked lists:

• There are mainly three types of linked lists:


1.Single-linked list
2.Double linked list
3.Circular linked list
1. Single-linked list:
• In a singly linked list, each node contains a reference to
the next node in the sequence. Traversing a singly
linked list is done in a forward direction.
2. Double-linked list:
• In a doubly linked list, each node contains references to
both the next and previous nodes. This allows for
traversal in both forward and backward directions, but it
requires additional memory for the backward reference.
3. Circular linked list:

• In a circular linked list, the last node points back to the
head node, creating a circular structure. It can be either
singly or doubly linked.
Operations on Linked Lists
1.Insertion: Adding a new node to a linked list involves
adjusting the pointers of the existing nodes to maintain
the proper sequence. Insertion can be performed at the
beginning, end, or any position within the list
2.Deletion: Removing a node from a linked list requires
adjusting the pointers of the neighboring nodes to
bridge the gap left by the deleted node. Deletion can be
performed at the beginning, end, or any position within
the list.
3.Searching: Searching for a specific value in a linked
list involves traversing the list from the head node until
the value is found or the end of the list is reached.
Advantages of Linked Lists

• Dynamic Size: Linked lists can grow or shrink


dynamically, as memory allocation is done at runtime.

• Insertion and Deletion: Adding or removing elements


from a linked list is efficient, especially for large lists.

• Flexibility: Linked lists can be easily reorganized and


modified without requiring a contiguous block of
memory.
Disadvantages of Linked Lists

• Random Access: Unlike arrays, linked lists do not allow


direct access to elements by index. Traversal is required
to reach a specific node.

• Extra Memory: Linked lists require additional memory


for storing the pointers, compared to arrays.
Traversal of Singly Linked List

• In order to traverse the linked list, we initialize a pointer


with the head of the linked list. Now, we iterate till the
pointer does not point to null. In each iteration, we print
the value of the node to which the pointer currently
points to and move the pointer to the next node.
Step-by-step algorithm:
• First, we will initialize a pointer to the head node of the
singly linked list.
• Second, we will check that the pointer is null or not null,
if it is null then return.
• While the pointer is not null, we will access the data or
element present on that node and store it in some
variable to print side by side, then we move the pointer
to next node.
• we will keep on checking the pointer is null or not null,
until it reaches to the end of the list.
• Things to Remember about Linked List
• head points to the first node of the linked list
• next pointer of the last node is NULL, so if the next
current node is NULL, we have reached the end of the
linked list.
• In all of the examples, we will assume that the linked list
has three nodes 1 --->2 --->3 with node structure as below:

Struct node {
int data;
struct node * next ;
}
• Displaying the contents of a linked list is very simple.
We keep moving the temp node to the next one and
display its contents.
1. Time Complexity
• Operations Average case time complexity Worst-case time complexity
• Insertion O(1) O(1)
• Deletion O(1) O(1)
• Search O(n) O(n)

• (Where 'n' is the number of nodes )


2. Space Complexity

Operations Space complexity

Insertion O(n)

Deletion O(n)

Search O(n)

You might also like