CAllocating Memory with malloc()

Allocating Memory with malloc()

malloc() (short for "memory allocation") is the most fundamental way to request memory from the heap in C. It is declared in <stdlib.h> and lets you ask for a block of memory of any size, at runtime, without knowing that size at compile time.

C
void *malloc(size_t size);
You pass it the number of bytes you want, and it returns a void * — a generic pointer to the first byte of a block of memory that is at least that large. If the allocation fails (the system has no more memory to give), it returns NULL instead.
A Basic Example
The most common pattern is to allocate enough space for some number of elements of a given type, using sizeof so the code stays correct even if the type changes later:

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

int main(void) {
    int n = 5;
    int *arr = malloc(n * sizeof(int)); // request room for 5 ints

    if (arr == NULL) {
        fprintf(stderr, "Allocation failed\n");
        return 1;
    }

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

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

    free(arr); // release it when you're done -- see the "free()" page
    return 0;
}
0
10
20
30
40
No Cast Needed in C
Because malloc() returns void *, and C automatically converts a void * to any other pointer type when needed, you do not need to cast the result:

C
int *arr = malloc(n * sizeof(int));         // preferred in C
int *arr2 = (int *) malloc(n * sizeof(int)); // also compiles, but unnecessary
This is a C vs C++ difference
In C++, void * is not implicitly converted to other pointer types, so a cast is required there. In plain C it is not required, and many C style guides (including advice from Peter van der Linden and the comp.lang.c FAQ) actively discourage the cast: it can silently hide the bug of forgetting to #include <stdlib.h>, and it adds visual noise for no benefit.
Always Check for NULL
malloc() can fail — most commonly when the system is out of memory, or when you ask for an unreasonably large size (for example due to an integer overflow in your size calculation). When it fails, it returns NULL, and it is your job to check for that before using the pointer.
Skipping the NULL check leads to undefined behavior
Dereferencing a NULL pointer (for example, writing arr[0] = 1; when arr is NULL) is undefined behavior — on most systems it crashes immediately with a segmentation fault, but it is not guaranteed to fail loudly or immediately. Production code, and honestly any code you care about, should check every allocation:

C
int *arr = malloc(n * sizeof(int));
if (arr == NULL) {
    // handle the failure -- log it, return an error code, exit, etc.
    // do NOT continue on and use 'arr' as if it were valid
    return -1;
}
malloc() Does Not Initialize Memory
The contents are garbage until you set them
malloc() only reserves space — it does not clear or initialize it. The bytes you get back could be leftover data from something else that used that memory previously. Reading an element before writing to it first will give you an unpredictable, meaningless value. If you need memory that starts zeroed, use calloc() instead (covered on the next page), or zero it yourself with memset().

C
int *arr = malloc(5 * sizeof(int));
printf("%d\n", arr[0]); // garbage value -- undefined, not necessarily 0!
  • malloc(size) requests size bytes from the heap and returns a void *, or NULL on failure

  • In C, the return value does not need to be cast -- many style guides recommend against casting it

  • Always check the return value for NULL before using it -- dereferencing a NULL pointer is undefined behavior

  • Memory from malloc() is uninitialized -- it contains garbage, not zeros, until you write to it

  • Every successful malloc() must eventually be matched with exactly one free()