December 22, 2024

malloc() Function and Dynamic Allocation of Memory in C programming Language

In this C programming tutorial, we explain the basics of memory allocation and the function malloc(). The YouTube tutorial is given below.

Main Things to Remember About the malloc() Function

  • the malloc() function is used to allocate (reserve) the memory at the runtime. The reserved memory is on the free store (also known as heap).
  • the malloc() function is defined in the standard header file <stdlib.h> :

    void * malloc( size_t size );
  • malloc() function takes only a single input argument! This argument is the total number of bytes of storage to allocate. For example, to store an integer on my computer (x64 architecture), we need 4 bytes. Often, we use the sizeof() operator to automatically determine how many bytes a data type or some other user-defined object occupies in the memory space. That is, we will use malloc function like this (for more details, see the code given in the next section):

     int *p =(int*) malloc(sizeof(int));
  • malloc() function returns a void pointer. Consequently, this void pointer is either automatically or manually type casted to the correct data type we plan to use.
  • Once we are finished with all the operations, we need to release or free the memory allocated by the function malloc. To do that, we need to call the function free(). The input argument of this function is the pointer that is returned by the malloc function. If we do not call free after the main code completes, we will create a memory leak which is a serious bug.

Minimal code example that explains how to use malloc – Example 1

The example given below explains how to correctly allocate the memory by using the malloc function and how to free the memory by using the free function. We explain how to allocate memory for a single integer.

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

int main()
{
    int *p =(int*) malloc(sizeof(int));

    if (p)
    {
        *p=100;
        printf("The value stored in the memory address that p points to is %d \n", *p);
        printf("The address stored in p is %p \n ",(void *)p);

    }
    free(p);
    p=NULL;
    return 0;

}

In this code, we first reserve memory space for storing a single integer. To do that, we call the malloc function like this

  int *p=(int*) malloc(sizeof(int));

The sizeof() operator will return a number of bytes necessary to store an integer. In our case, the number of bytes is 4. Then, malloc function will reserve 4 bytes on the free store and it will return a pointer (memory address) to the beginning of the reserved memory space. This pointer is the void pointer. We type cast this pointer to int*. We actually do not need to do that since the compiler will do that automatically. The pointer p will contain the address of the beginning of the memory space allocated by the malloc function.

If for some reason the malloc function was not able to reserve the memory, the malloc function will return a null pointer. That is why in the code we have the if() statement. The if statement will simply check if the pointer p is a null pointer or not. If it is a null pointer, the block under the if statement will not be executed. If the pointer p is not a null pointer, then we assign the value and print both the value and the address of the pointer p.

Finally, we free the allocated memory by using the free() function, and we set p to be a null pointer.

Further explanations are given in the figures below.

Minimal code example that explains how to use malloc for reserving space for arrays – Example 2

The example given below explains how to allocate the memory space for an array. The principle is the same. We use the malloc function to reserve the complete memory space. In our case, the goal is to store 6 array entries of the array of the type int. The code is self-explanatory.

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

int main()
{
    size_t sizeInt = sizeof(int);
    size_t capacity=6;

    int *p = malloc(sizeInt*capacity);

    if (p)
    {
        p[0]=1; p[1]=2; p[2]=-3; p[3]=10; p[4]=-15; p[5]=17;
    }
    
    for (size_t i=0; i<capacity; i++ )
    {
        printf("%d \n ",p[i]);
    }

    free(p);
    p=NULL;
    return 0;
    
    
    return 0;

}