Signup/Sign In

Dynamic Memory Allocation in C

In C language, the process of allocating memory at runtime is known as dynamic memory allocation. Library functions known as memory management functions are used for assigning (allocating) and freeing memory, during execution of a program. These functions are defined in the stdlib.h header file.

These functions allocate memory from a memory area known as heap and when the memory is not in use, it is freed to be used for some other purpose. We access the dynamically allocated memory using pointers

We have done static memory allocation till now. The memory requirement was fixed. It could not be increased or decreased during execution of the program. This type of allocation has a drawback. We cannot predict how much memory will be required. For example, if we declare an array, like this:

int marks[50];

We might only store data for 25 students. As a result, memory will be wasted. Or we may need to store data for 60 students, in that case we will have less memory. The solution to these problems is dynamic memory allocation.

Difference between Static and Dynamic Memory Allocation

Before we move on to study dynamic memory allocation in detail, let’s take a look at the differences between static and dynamic memory allocation.

Static Memory Allocation

Dynamic Memory Allocation

Allocation is done before execution of the program(at compile time).

Allocation is done during execution of the program(at runtime).

Here, variables are allocated memory permanently.

Here, memory is allocated only when the program is active.

It uses stack for managing memory allocation.

It uses heap for managing memory allocation.

We cannot reuse the memory.

We can reuse the memory and free it after usage.

Execution is faster than dynamic memory allocation.

Execution is slower than static memory allocation.

It is less efficient.

It is more efficient.

    It is simple to use.

It can be complicated to use.

FunctionDescription
malloc()allocates requested size of bytes and returns a void pointer pointing to the first byte of the allocated space
calloc()allocates space for an array of elements, initialize them to zero and then returns a void pointer to the memory
freereleases previously allocated memory
reallocmodify the size of previously allocated space

Memory Allocation Process

Global variables, static variables and program instructions get their memory in permanent storage area whereas local variables are stored in a memory area called Stack.

The memory space between these two region is known as Heap area. This region is used for dynamic memory allocation during execution of the program. The size of heap keeps changing.

dynamic memory allocation in c


Allocating block of Memory

Now let's see how the different functions for dynamic memory allocation works.

1. malloc() Function

malloc() function is used for allocating block of memory at runtime. This function reserves a block of memory of the given size and returns a pointer of type void. This means that we can assign it to any type of pointer using typecasting. If it fails to allocate enough space as specified, it returns a NULL pointer.

Syntax:

Here is the syntax of this function,

void* malloc(size_t size)

In stdlib.h, size_t is defined as unsigned int.

The memory allocated by malloc() contains garbage value.

We use this function like this,

data_type *ptr;
ptr = (data_type *)malloc(specified size);

Here, we typecast the pointer returned by malloc() function using (data_type *).

For example:

void main(){
    int *x;
    float *y;
    x = (int*)malloc(50);     //50 contiguous bytes of memory are allocated and the address of the first byte is stored in x.

    y = (float*)malloc(5 * sizeof(float);    // This allocates memory to store 5 decimal numbers.
    // we should always check the value returned.
    if(x == NULL)
        printf(“Memory unavailable\n”);
    if(y == NULL)
        printf(“Memory unavailable\n”);
}

Let's take another example:

#include<stdio.h>
#include <stdlib.h>
int main(){
    int *ptr;
    ptr = malloc(5 * sizeof(int)); /* a block of 5 integers */
    if (ptr != NULL) {
        *(ptr + 1) = 10; /* assign 10 to second integer */
        printf("Value of the 2nd integer is %d",*(ptr + 1));
    }
    return 0;
}


Value of the 2nd integer is 10


2. calloc() Function

calloc() is another memory allocation function that is used for allocating memory at runtime. calloc function is normally used for allocating memory to derived data types such as arrays and structures. If it fails to allocate enough space as specified, it returns a NULL pointer.

The memory allocated by calloc() is initialized to zero.

Syntax:

Let's see the syntax for this function,

void *calloc(number of items, size_t size);

Time for an Example: calloc() function

Here is a simple code example,

char * ptr;
ptr = (char*)calloc(5, sizeof(char);

Let's look at another example,

struct employee
{
    char *name;
    int salary;
};
typedef struct employee emp;
emp *e1;
e1 = (emp*)calloc(30, sizeof(emp));

3. realloc() Function

The realloc() function is used to change the memory size that is already allocated dynamically to a variable.

If we want to change the size of memory allocated by malloc() or calloc() function, we use realloc() function. Without losing the old data, it changes the size of the memory block. The first argument of this function is a pointer pointing to the block of memory we allocated before and the second argument is the updated size of the memory block. On failure, it returns NULL.

If the new size(of memory required) is larger than the old size, it retains the data and newly allocated bytes are uninitialized. It might move the old data to a new block of memory with increased size if there's not enough space at the old address.

Syntax:

Let's see the syntax for this function,

void* realloc(void *pointer, size_t new-size);

Time for an Example: realloc() function

Let's see, how we can use this function.
int *x;
x = (int*)malloc(50 * sizeof(int));
x = (int*)realloc(x, 100);   //allocated a new memory to variable x

Another example depicting the use of realloc() function.

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int x,*ptr;
    ptr = (int*)malloc(5 * sizeof(int));
    if(ptr == NULL){
        printf("Memory not available");
        exit (1);
    }
    for(int i = 0; i < 5; i++)
        scanf("%d", ptr + i);
    ptr = (int*)realloc(ptr, 7 * sizeof(int));
    if(ptr == NULL){
        printf("Memory not available");
        exit (1);
    }
    for(int i = 5; i < 7; i++)
        scanf("%d", ptr + i);
    for(int i = 0; i < 7; i++)
        printf("%d : %d\n",i + 1, *(ptr + i));
    free(ptr);
    return 0;
}


5 4 6 7 8 3 2
1 : 5
2 : 4
3 : 6
4 : 7
5 : 8
6 : 3
7 : 2


Diffrence between malloc() and calloc()

calloc() Functionmalloc() Function
calloc() function initializes the allocated memory with 0 value.malloc() function initializes the allocated memory with garbage values.
Number of arguments is 2Number of argument is 1

Syntax:

(cast_type *)calloc(blocks, size_of_block);

Syntax:

(cast_type *)malloc(size_in_bytes);

4. free() Function

Let's start by knowing the syntax of this function:

void free(void *p);

The memory we allocate dynamically exists till the end of the program. As a programmer, it is our duty to release that memory so that it can be used for other purposes and does not cause memory leaks. We do it as follows:

int *x;
x = (int*)malloc(50 * sizeof(int));
free(x);

When we allocate dynamic memory in functions, if the function does not return address of the memory dynamically allocated, the memory should be free within that function itself. But if the function returns the dynamically allocated memory's address, then the momory has to be freed in the calling function.

Program to represent Dynamic Memory Allocation(using calloc())

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i, n;
    int *element;

    printf("Enter total number of elements: ");
    scanf("%d", &n);

    /*
        returns a void pointer(which is type-casted to int*)
        pointing to the first block of the allocated space
    */
    element = (int*) calloc(n,sizeof(int)); 
    
    /*
        If it fails to allocate enough space as specified, 
        it returns a NULL pointer.
    */
    if(element == NULL) 
    {
        printf("Error.Not enough space available");
        exit(0);
    }

    for(i = 0; i < n; i++)
    {
        /*
            storing elements from the user 
            in the allocated space
        */
       scanf("%d", element+i); 
    }
    for(i = 1; i < n; i++)
    {
       if(*element > *(element+i))
       {
            *element = *(element+i);
        }
    }

    printf("Smallest element is %d", *element);

    return 0;
}


Enter total number of elements: 5 4 2 1 5 3 Smallest element is 1

In this way, we can make use of dynamic memory allocation in our program.

So this was all about dynamic memory allocation in C language where we used malloc() function, calloc() function, realloc() function, and free() function.