DEV Community

Cover image for Understanding Heap Memory Allocation in C - Malloc and Free
Scott
Scott

Posted on

Understanding Heap Memory Allocation in C - Malloc and Free

Malloc and Free are the most common functions used for heap memory management. These functions provide the following advantages over sbrk and brk:

  1. They are standardized as part of the C language.
  2. They are easier to use with threaded programs.
  3. They provide a simple interface for memory to be allocated, especially in smaller units.
  4. Allow the arbitrary deallocation of blocks of memory.

Malloc takes in a size as an argument and returns a pointer to the newly allocated block of memory that is of the size specified in the argument. The allocated memory is not initialized.

The free function takes in a pointer to a block of allocated memory. The function will then add the block of memory to a list of free blocks, which are recycled by future malloc calls.

When malloc is called, it will generally complete the following steps:

  1. Check if there is a block of memory in the list of free blocks large enough to allocate for the memory request.
  2. If no free blocks are available, allocate a new block of memory to use.

Based on this process, it is important to note that when malloc is called, it does not always increase the program break. This is because in some cases, the memory may be available in the list of free blocks, meaning no new memory needs to be allocated to the heap.

With this basic understanding of malloc, let's look at a simple example of a malloc in C.

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

struct s{
    int value;
};

int main(int argc, char *argv[]){

    struct s *newS = malloc(sizeof(struct s));
    newS->value = 10;

    printf("%d\n", newS->value);
    free(newS);

    return 0;
}
Enter fullscreen mode Exit fullscreen mode

In this example, we have a struct named s which contains a single property, value. To be able to use this struct, we need to allocate some memory for it. To do this, we use a malloc as shown in the first line of the main function. The argument for our malloc call is sizeof(struct s). This operation determines how much memory is required to contain our struct s, allocates a memory block of this size, and returns a pointer of the block to the variable newS.

With newS initialized, we can start to work with its property value. To access the property, we use the pointer notation newS->value. The line after the allocation shows how to set the value, and the print shows how to access the value.

At the end of the program, we no longer need the memory assocaited with newS. We make a call to the free function, providing newS as an argument. This will add the memory associated with newS to the free list, allowing it be used for future malloc calls.

It’s important to note that when the process terminates, all of its memory is returned to the system, so free isn’t actually required for this simple program. Free is generally used in more complex programs to make the program more readable and to help with efficient memory management.

You now know the basics of working with malloc and free!

Top comments (1)

Collapse
 
pauljlucas profile image
Paul J. Lucas

If you're going to talk about malloc(), you ought to mention its related functions, e.g., realloc() and calloc().

If you're going to talk about free(), you ought to mention that free() of a null pointer is guaranteed to do nothing.