C Language Allocating Memory


Example

Standard Allocation

The C dynamic memory allocation functions are defined in the <stdlib.h> header. If one wishes to allocate memory space for an object dynamically, the following code can be used:

int *p = malloc(10 * sizeof *p);
if (p == NULL) 
{
    perror("malloc() failed");
    return -1;
}

This computes the number of bytes that ten ints occupy in memory, then requests that many bytes from malloc and assigns the result (i.e., the starting address of the memory chunk that was just created using malloc) to a pointer named p.

It is good practice to use sizeof to compute the amount of memory to request since the result of sizeof is implementation defined (except for character types, which are char, signed char and unsigned char, for which sizeof is defined to always give 1).

Because malloc might not be able to service the request, it might return a null pointer. It is important to check for this to prevent later attempts to dereference the null pointer.

Memory dynamically allocated using malloc() may be resized using realloc() or, when no longer needed, released using free().

Alternatively, declaring int array[10]; would allocate the same amount of memory. However, if it is declared inside a function without the keyword static, it will only be usable within the function it is declared in and the functions it calls (because the array will be allocated on the stack and the space will be released for reuse when the function returns). Alternatively, if it is defined with static inside a function, or if it is defined outside any function, then its lifetime is the lifetime of the program. Pointers can also be returned from a function, however a function in C can not return an array.

Zeroed Memory

The memory returned by malloc may not be initialized to a reasonable value, and care should be taken to zero the memory with memset or to immediately copy a suitable value into it. Alternatively, calloc returns a block of the desired size where all bits are initialized to 0. This need not be the same as the representation of floating-point zero or a null pointer constant.

int *p = calloc(10, sizeof *p);
if (p == NULL) 
{
    perror("calloc() failed");
    return -1;
}

A note on calloc: Most (commonly used) implementations will optimise calloc() for performance, so it will be faster than calling malloc(), then memset(), even though the net effect is identical.

Aligned Memory

C11

C11 introduced a new function aligned_alloc() which allocates space with the given alignment. It can be used if the memory to be allocated is needed to be aligned at certain boundaries which can't be satisfied by malloc() or calloc(). malloc() and calloc() functions allocate memory that's suitably aligned for any object type (i.e. the alignment is alignof(max_align_t)). But with aligned_alloc() greater alignments can be requested.

/* Allocates 1024 bytes with 256 bytes alignment. */
char *ptr = aligned_alloc(256, 1024);
if (ptr) {
    perror("aligned_alloc()");
    return -1;
}
free(ptr);

The C11 standard imposes two restrictions: 1) the size (second argument) requested must be an integral multiple of the alignment (first argument) and 2) the value of alignment should be a valid alignment supported by the implementation. Failure to meet either of them results in undefined behavior.