advanced22 min

Dynamic Memory with malloc and free

Allocating heap memory at runtime, and the leak/dangling-pointer risks of managing it yourself.

What you'll learn

  • Allocate heap memory with malloc and check whether it succeeded
  • Release allocated memory with free once it's no longer needed
  • Explain what a memory leak and a dangling pointer are, and how to avoid each

Explanation

So far, every variable's size has been fixed and known at compile time. malloc (from <stdlib.h>) lets a program request a block of memory at runtime, from a region called the heap: int *arr = malloc(3 * sizeof(int)); requests enough space for 3 ints and returns a pointer to the start of that block. malloc can fail (e.g. if the system is out of memory), returning NULL in that case -- production code should always check for this before using the returned pointer.

Memory obtained from malloc is not automatically cleaned up when it goes out of scope, unlike a local variable's stack memory. You must explicitly release it with free(arr); once you're done with it. Forgetting to call free on memory you no longer use is a memory leak -- the memory stays reserved for the rest of the program's run, unusable by anything else, even though nothing in your program can reach it anymore.

There's a danger on the other side too: a dangling pointer is a pointer that still holds the address of memory that has already been freed. Using it after the free call (reading, writing, or calling free on it a second time) is undefined behavior -- it might appear to work, corrupt unrelated data, or crash, unpredictably. A common defensive habit is setting a pointer to NULL immediately after freeing it (free(arr); arr = NULL;), so any accidental later use fails predictably and safely rather than silently corrupting memory.

Guided lab

Guided edit: Adding free() to a heap allocation

CNot executed
This lab does not run in your browser or on VisaSparkSchools's servers. Read the code, follow each edit step by step and see the expected output after every change.

Follow each step to see how adding free() changes this program's resource hygiene.

Step 1 of 2

Start with a heap allocation that's used but never freed. This is a memory leak -- a real bug, even though it doesn't change this program's printed output, since the program exits immediately afterward anyway.

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

int main(void) {
    int *arr = malloc(3 * sizeof(int));
    if (arr == NULL) {
        printf("Allocation failed\n");
        return 1;
    }

    for (int i = 0; i < 3; i++) {
        arr[i] = (i + 1) * 10;
    }

    int sum = 0;
    for (int i = 0; i < 3; i++) {
        sum += arr[i];
    }
    printf("Sum: %d\n", sum);

    return 0;
}

Stuck? Get a hint.

Common mistakes

  • Forgetting to call free() on heap memory once it's no longer needed, causing a memory leak.
  • Using a pointer after calling free() on it (a dangling pointer), or calling free() on the same pointer twice.
  • Not checking whether malloc returned NULL before using the pointer it returned, assuming allocation always succeeds.

Knowledge check

Knowledge check

1. What does malloc return if it fails to allocate the requested memory?
2. What is a memory leak?
3. What is a dangling pointer?

Takeaway

Every successful malloc needs a matching free once the memory is no longer needed -- and setting a pointer to NULL right after freeing it helps catch accidental reuse.

Summary

malloc requests heap memory at runtime and can fail (returning NULL); free releases it explicitly, since heap memory isn't cleaned up automatically -- forgetting free leaks memory, and using freed memory creates a dangling pointer.

References

Your notes

Notes save automatically.

Finished this lesson?

Mark it complete to track your progress and schedule a future review.

Next: Structs and typedef