Memory management is one of the most fundamental and important aspects of any computer programming language. In many programming languages, you don’t have to worry about memory management, but in C Programming Language you do memory management manually. C is one of the most powerful programming languages. Pointer is one of the most powerful features of the C programming language which gives you the ability to point memory locations. This feature enables easy memory access.
As we all know computer memory is made up of a large number of cells, which are further organized as addressable registers. Each register is responsible to store a sequence of bits. So it is always necessary to manage these memory locations effectively to increase utilization.
Types of memory allocations in C
There are two ways in which memory can be allocated in C
- Static memory allocation or Compile time allocation
- Dynamic memory allocation or Run time allocation
Static or compile-time memory allocation
In this method desired memory is allocated at the time of variable declaration or beginning of the program. The amount of memory allocation is fixed and is determined at the time of program compilation.
Example:
1 |
int a,b; |
when the first statement int a,b; is compiled 4 consecutive bytes(integer occupies 4 bytes in a 32-bit machine) for each variable a,b will be allocated.
Drawbacks of static memory allocation
- If we declare more number of elements and we are using less number of elements then the memory allocated for the not used variables will be wasted. The unused memory cells are not made available to other applications. This leads to inefficient use of memory.
- The size of the data type or variable must be known before.
- We can not change the size of a variable at run time.
Dynamic or Runtime C Memory Allocation
In C Programming Language it is not always possible to predict the memory requirement for the program, so it is better to allocate the memory in real-time whenever required, it makes efficient use of memory.
C Programming Language provides the following dynamic allocation and deallocation functions –
- malloc()
- calloc()
- realloc()
- free()
malloc,calloc, and realloc are used for memory allocation and deallocation is achieved by the use of the free function.
Allocating A Block of Memory-malloc()
The malloc() function allocates the memory at run time whenever required. It allocates the memory block with the required number of contiguous bytes in the c memory management system and returns the pointer to the first byte(base address) or null if there is some error occur.
Syntax:
1 |
pointer=(data-type *)malloc(block_size); |
Example:
1 2 3 |
int * p; p = (int *) malloc (sizeof (int)); * p = 5; |
- First, we declare a pointer variable ‘p’.
- Then the pointer itself is equal to a pointer type int that contains the memory address space for an int.
- Size () return the space it occupies what you want, if you put int in, such as 2 bytes, because we have assigned two bytes.
- Finally, now that the pointer is contained, we give a value.
Allocating Multiple blocks of Memory-calloc()
The calloc() function is the same as malloc() except it is used to allocate multiple c memory management blocks of the same size then all bytes sets to zero.
Syntax:
1 |
pointer=(data-type *)calloc(n,sizeof(block_size)); |
It allocates contiguous space for ‘n’ blocks, each of the size of block_size bytes. All bytes are initialized to zero and a pointer to the first byte of the allocated memory block is returned.
1 |
calloc(m,n) is equivalent to p=m*malloc(n); |
Example:
An int array of 10 elements can be allocated as follows.
1 |
int * array = (int *) calloc (10, sizeof (int)); |
We can achieve the same using the malloc() function as below –
1 |
int * array = (int *) malloc (sizeof (int) * 10); |
However, an area reserved by the malloc() function for the states that are undefined, the area allocated by the calloc function contains a 0.
Difference between malloc() and calloc()
- the malloc() allocates bytes of memory but calloc() allocates blocks of memory.
- the malloc() takes a single argument(memory required in bytes) but calloc() takes 2 arguments (number of variables to allocate memory, size in bytes of a single variable)
- The memory allocated using the malloc() function contains garbage values, the memory allocated by the calloc() function contains the value 0.
Resize the size of a Memory-realloc()
The realloc() function allows us to reset the size of the allocated area.
Syntax:
1 |
ptr=realloc(ptr,new_size); |
Where ptr is holding the current base address of the memory block and new_size holds the size in bytes.
Releasing the used memory-free()
The free() function is used to deallocate the allocated memory using the malloc() or calloc() function. It is always important to release the memory that is not in use, so it can be used in the future.
Syntax:
1 |
free(ptr); |
Note:- ptr must be a valid pointer to the address otherwise it can result in a system crash.
Example Program:
Below is the program where we have allocated memory for ptr integer pointer with the byte required for int data type, then assigned value 10. Finally released memory using free() function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#include<stdio.h> int main() { int *ptr; ptr = (int *)malloc(sizeof(int)); if (ptr== 0) { printf("ERROR: Out of memory\n"); return 1; } *ptr = 10; printf("%d\n", *ptr); free(ptr); return 0; } |