Hello and welcome!
In this video session we will discuss the memory allocations used in Linux system programming.
In this session we will be discussing the below topics such as malloc, Calloc, realloc, allocate
free functions and break and s break system calls.
As a note, break in is break or system calls on which the library functions such as malloc, calloc,
and realloc are built.
In the previous session, we had discussed that a process allocates a dynamic memory in the heap segment.
The memory allocated in the heap segment is contiguous virtual memory, and the heap memory begins after
the uninitialized data segment and the heap grows and shrinks based on the program requirement.
So whenever there is an allocation of memory, the heap grows and it shrinks when the dynamic memory
allocator is freed.
Now let's discuss program break in dynamic memory.
The heap is a place where the dynamically allocated memory is being placed.
But before using heap, there is a program break which refers to the current limit of the heap.
So the current limit of the heap is referred to as a program break.
When dynamic memory is allocated, the program break increases.
After the program break is increased, the process may access any address in the newly allocated area.
We had visited similar diagram before when we discussed the virtual memory.
So here we have a initialized data and uninitialized data.
The memory segment after uninitialized data segment is called heap.
So the start of the heap begins from this point.
And initially when the program runs, there is a program break which points to the start of the heap.
So whenever any dynamic memory allocation is performed, we need to advance the program break in memory
location so that the memory that is advanced can be used for further dynamically allocated memory.
Let's say that user needs 100 bytes of data.
The program break is pushed to the required number of bytes, and after that the memory can be utilized
for dynamic memory allocations.
So the function calls such as malloc, calloc, and realloc internally rearranges the program break
in such a way that the newly available memory can be utilized by the program for dynamic memory allocations.
Now let's see a system call called break and s break.
As we have discussed earlier, break and break are system calls on which library functions such as malloc,
calloc, and realloc are built.
But as a note, the user rarely uses system calls such as break or s break.
Most of the time the user uses the library functions such as malloc, calloc, and realloc.
So understanding the break and s break will give us a good idea of how the dynamic memory allocation
on heap works.
In the syntax of break system call, we need to include unistd.h and the syntax of break is as follows.
It takes the new memory location in the heap area, and it returns either success or failure.
On success, it returns a zero.
On failure, it returns minus one.
This points to the newly allocated memory location.
For example, let's say that our current program break is at this point and we need a memory after the
program break.
So now the break.
The program break is being moved to the new memory location.
As we have discussed the break system call on Success sets program break to the new memory location
specified by the break system call.
So whatever memory location we specify here, the program break advances to that memory location after
the memory program break has been advanced to that new memory location.
The allocated bytes can be used for dynamic memory allocations.
And there is one more form of break that is s break.
The only difference between break and s break is in s break.
We specify the amount of memory that needs to be incremented from the reference program break.
This means, for example, let's say that if we want to use s break here and we already have a program
break pointing to the top of the memory where the memory can be allocated using s break, we have to
specify the number of offset bytes we need to move the program break.
So let's say we give a parameter as ten bytes.
Then the program break advances by ten bytes based on the system call.
On failure it returns a minus one which is type casted to void WordStar, and it sets the error number,
which is a global parameter to enomem, which means system is out of memory.
And in case of success, it returns the pointer to newly allocated memory where the program break has
advanced.
Now let's see the malloc library function call.
Malloc is a library function call where break and break are the system calls.
In general, C program uses malloc family of functions to allocate and deallocate memory on the heap.
These functions are built over break and break, as we have discussed earlier in the syntax of malloc.
We have to include stdlib.h, and we have to specify the number of bytes that needs to be allocated.
And it returns a pointer type casted to White Star, which points to the memory location where memory
is allocated.
In case of malloc has failed, it returns a null.
Now let's see the next function.
Kellogg.
The Kellogg syntax is shown here.
In Kellogg, we specify the size of block and number of times the size needs to be allocated.
For example, let's say we want a memory for ten integers.
Then we have to mention size of int and how many such integers we need.
This is a very generic syntax which can be used to allocate different types of data types.
For example, let's say we have a structure with different data elements in it.
Then we have to specify the size of one structure followed by number of such structure elements we need.
So for example, size of one structure into ten allocates total ten such structures and provides us
the pointer to memory allocated.
The only difference between malloc and calloc is in case of malloc it allocates the memory, but it
does not assign any value to the allocated memory, whereas in calloc the entire allocated memory is
filled with zero.
Now let's see the next set of function that is realloc.
In order to use realloc, we need to include Stdlib.h, and Realloc is used when.
Let's say we already have allocated some bytes of memory, but during the execution, we have found
that the dynamically allocated memory size may alter, meaning it may increase or it may decrease.
So in this case we can make use of Realloc to resize the memory previously allocated using malloc or
calloc in realloc.
We specify the pointer that we have got previously by malloc or calloc, and we specify the new size
that is required.
Realloc in turn, returns a pointer to the allocated memory on success or null pointer on error.
In case we are increasing the size of the block of memory.
Realloc attempts to form a single block.
As we have discussed, memory allocations gives a contiguous set of memory on the heap.
If the block lies at the end of the heap, then realloc expands the heap.
If the block of memory lies in the middle of the heap, then there is insufficient free space immediately
following it.
Realloc allocates a new block of memory and copies all the existing data from the old block to the new
block.
So this is the case where the allocated memory is in between the heap and when the new memory needs
to be increased.
In this case, it cannot be increased by just adding some more bytes because there are other allocated
memory.
So in this case, a new set of memory is allocated on the heap and the old memory contents are copied
onto the newly allocated memory and it returns the pointer to the newly allocated memory.
In this case, care must be taken as the old memory location and the newly allocated memory location
may not be the same, hence storing the memory address before relocate and later using the same memory
after realloc may give wrong results.