malloc() & free() in C

Memory Management is one of the most critical aspects of programming in C/C++. In this lecture, we will discuss about two fundamental functions in C/C++ for the memory management i.e. malloc() and free().

malloc() Function

Using malloc() function, we can dynamically allocate a large chunk of memry on heap by specifying its size in bytes.

To use the malloc() function, we need to include the stdlib.h header file.

Syntax for the malloc() function:

void* malloc(size_t size);

Here, size_t is an unsigned integer type, and represents the size in bytes, that needs to be allocated from heap. The malloc() function returns a void pointer, and we can cast this void pointer into a pointer of any type.

If successful in allocating the memory on heap, the malloc() function returns a pointer pointing to the first byte of the allocated space. Otherwise, it returns a NULL pointer.

Let’s see an example,

int n = 5;
int *ptr = (int*) malloc(n * sizeof(int));

If the size of an integer is 4 bytes, then the malloc() function above allocated 5 * 4, which is 20 bytes. This amount of memory can hold the values of 5 integers. The malloc() function returns a pointer of void type, pointing to the start of this memory location. We casted it into an integer pointer ptr.



    Now, using the pointer ptr, we can access all the 5 inetegers allocated on the heap. For example, to assign a value to the first element, we can apply the dereference operator on the pointer ptr like this:

    *ptr = 55;
    

    Or we can use the subscript operator i.e.

    ptr[0] = 55;
    

    It will assign the value 55 to first integer in the allocated memory.

    As pointer ptr is of integer type, so to access the second integer, we can increment the pointer ptr by one and then dereference it like this:

    *(ptr + 1) = 66;
    

    Or we can use the subscript operator i.e.

    ptr[1] = 66;
    

    It will change the value of the second integer in the memory allocated on the heap.

    Casting from a void pointer to a proper data type pointer is essential, so that we can access the individual elements in this allocated memory using pointer arithmetic.

    If the malloc() function fails to allocate memory on the heap, it will return NULL. Therefore, we should always first check if the returned pointer is NULL or not. Only then should we try to access the elements in the allocated memory. Like this,

    int n = 5;
    int *ptr = (int*) malloc(n * sizeof(int));
    
    if (ptr != NULL)
    {
        ptr[0] = 55;
        ptr[1] = 55;
        ptr[2] = 55;
        ptr[3] = 55;
        ptr[4] = 55;
    }
    

    free() Function

    Once memory is allocated in the heap and we no longer need it after accessing it, we should deallocate that memory. For this, we can use the free() function.

    To use the free() function, we need to include the header file stdlib.h.

    The syntax of the free() function is as follows,

    void free(void* ptr);
    

    It takes a pointer as an argument and deallocates the memory to which this pointer points. It does not return any value. It will deallocate the memory that was allocated on the heap by using malloc(). However, you need to ensure that the pointer you pass to the free() function points to a location where memory was allocated on the heap using malloc() or calloc(). Like this,

    int n = 5;
    
    int *ptr = (int*) malloc(n * sizeof(int));
    
    free(ptr);
    

    If you pass a null pointer to the free() function, nothing will happen. On the other hand, if you pass a pointer pointing to a memory location that was already deallocated, or it was not allocated by malloc() or calloc(), it can result in undefined behavior. Therefore, it’s crucial to use the free() function correctly to deallocate the memory that was allocated using malloc() or calloc(), and deallocation should only happen once. We should not attempt to free the same memory multiple times.

    Here’s a full example where we will allocate 20 bytes on the heap, which can hold 5 integer values. Then, we can use the subscript operator to access each individual element held by this memory chunk. After that, we will deallocate this memory by passing the pointer to the free() function.

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        int n = 5;
    
        // Allocate 20 bytes on heap
        int *ptr = (int*) malloc(n * sizeof(int));
    
        if (ptr != NULL) 
        {
            // Memory successfully allocated using malloc
    
            // populate the array
            for (int i = 0; i < n; ++i)
            {
                ptr[i] = i + 10;
            }
    
            // print the array
            for (int i = 0; i < n; ++i) 
            {
                printf("%d ", ptr[i]);
            }
            printf("\n");
        }
        else
        {
            printf("Memory not allocated.\n");
            exit(0);
        }
    
        return 0;
    }
    

    Output:

    10 11 12 13 14 
    

    There are certain things we need to keep in mind while using the malloc() and free() functions.

    Best Practices for malloc() & free()

    • malloc() can return null, so it’s always essential to check if the returned pointer is not null before trying to access the memory allocated by these functions.
    • If you allocate memory using malloc() and don’t deallocate it using the free() function, this can cause memory leaks which, over the long run, can crash your application.
    • If memory has already been deallocated using the free() function, don’t call the free() function on it again as it can lead to undefined behaviour.
    • Once a pointer has been freed, meaning the memory has been deallocated using the free() function, assign the pointer to null. This prevents freeing the memory again and also helps avoid dangling pointers.

    Summary

    The malloc() and free() functions provide a way to dynamically allocate and deallocate memory on the heap in C or C++, but it is essential to follow best practices to avoid memory leaks, undefined behavior, and other memory-related issues.

    Scroll to Top