Allocate memory


#include <stdlib.h>

void* malloc( size_t size );


The number of bytes to allocate.



Use the -l c option to qcc to link against this library. This library is usually included automatically.


The malloc() function allocates a buffer of size bytes. Use free() or realloc() to free the block of memory.

Note: Because the malloc() implementation uses signed, 32-bit integers to represent the size internally, you can't allocate more than 2 GB in a single allocation. If the size is greater than 2 GB, malloc() indicates an error of ENOMEM.

If size is zero, the default behavior is to return a non-NULL pointer that's valid only to a corresponding call to free() or realloc(). Don't assume that this pointer points to any valid memory. You can control this behavior via the MALLOC_OPTIONS environmental variable; if the value of MALLOC_OPTIONS contains a V, malloc() returns a NULL pointer. This environment variable also affects calloc() and realloc(). This is known as the "System V" behavior.

Note: If there isn't a free block of memory that's large enough to satisfy the request, the memory allocator uses mmap() to get memory from the system. The _amblksiz global variable (defined in <stdlib.h>) specifies the number of bytes that the allocator gets from the system. You can also use the mallopt() function to control how the system allocates memory.


A pointer to the start of the allocated memory, or NULL if an error occurred (errno is set).


Not enough memory.
No error.


#include <stdlib.h>

int main( void )
    char* buffer;

    buffer = (char* )malloc( 80 );
    if( buffer != NULL ) {
        /* do something with the buffer */

        free( buffer );
    return EXIT_SUCCESS;

Environment variables:

You can modify the allocator characteristics by setting the following environment variables, which control how memory is cached by the allocator, and when it's released back to the system:

The maximum number of cached arena blocks (the cache is used to track freed blocks that are held and not released back to the OS). The default value is 12.
The maximum size of the arena cache.
The size of the malloc() arena. It also controls the amount by which the arena grows.

By default, this is set to 32 KB, which results in a minimum allocation of 64 KB by the allocator. You can lower this as long as it's a multiple of the page size (4096). The allocator will still attempt to get memory from the system in multiples of this value, and since it creates buckets of varying sizes, it may choose to allocate core memory for a bucket of blocks of a new size, even though an earlier allocation of core memory for a block of a different size hasn't been fully exhausted.

Memory in the allocator is allocated with different policies for blocks smaller than 128 bytes and blocks larger than 128 bytes:

  • Smaller blocks are allocated using a fixed chunk allocator, which gets system memory in bunches of pieces of the size specified by MALLOC_ARENA_SIZE and creates smaller buckets from them.
  • Larger memory blocks are created by also getting core memory from the system in multiples of MALLOC_ARENA_SIZE and carving out the appropriate user pieces from this, putting the remaining space onto a free list.

So, for example, if you make a simple pair of allocations such as:


the system creates a 32 KB arena allocation for the bucket size of 128 bytes to service the 100-byte allocation, and a 32 KB arena allocation to service the 200-byte allocation.

Lowering MALLOC_ARENA_SIZE can reduce the amount of memory required.

If set, malloc() changes the free queueing strategy from the default (FIFO) to LIFO.
If this environment variable is nonzero, the heap will never shrink; freed blocks are never released back to the OS, but are maintained in the arena cache.
If this environment variable is nonzero, then when malloc() needs to expand the heap, it specifies the MAP_NOINIT flag when it calls mmap(); if the physical memory being mapped was previously unmapped with UNMAP_INIT_OPTIONAL, then the POSIX requirement that the memory be zeroed is relaxed. For more information, see "Initializing allocated memory" in the Interprocess Communication (IPC) chapter of the System Architecture guide.

There also other ways to control the exact distribution of sizes used to create small bands of memory and the threshold at which the smaller buckets end and the list-based allocator for larger blocks begins. This is also done with environment variables:

Use this environment variable to configure the bands of memory. The string format is:
N:s1,n1,p1:s2,n2,p2:s3,n3,p3: ... :sN,nN,pN

where the components are:

The band size.
The number of items.
The preallocation value, which can be zero.
If you specify the band configurations, you also have to set this environment variable to 1 to ensure that your configurations are picked.
Preallocate and populate the arena cache by setting this environment variable to a value that specifies the size of the total arena cache.
Control the way calloc(), malloc(), and realloc() behave if you specify a size of 0 (or a value of 0 for the n argument to calloc()). The V ("System V") and R ("use the realloc() behavior of QNX Neutrino 6.4.0 and earlier") columns below indicate how the functions behave if the value of MALLOC_OPTIONS includes that letter:
Function Default V R
calloc(n, 0) Non-NULL NULL No effect
malloc(0) Non-NULL NULL No effect
realloc(NULL, 0) Non-NULL NULL No effect
realloc(non-NULL, 0) Non-NULL NULL NULL

In all the above cases, if the function returns a non-NULL pointer, it's valid only for a corresponding call to free() or realloc().

For more information, see "Dynamic memory management" in the Heap Analysis: Making Memory Errors a Thing of the Past chapter of the Neutrino Programmer's Guide.


The debug malloc library also uses these environment variables:

Enable some initial verbose output regarding other variables that are enabled.
The depth of the backtrace for allocations (i.e. where the allocation occurred) on CPUs that support deeper backtrace levels. Currently the builtin-return-address feature of gcc is used to implement deeper backtraces for the debug malloc library. The default value is 0.
Set the depth of the backtrace for errors and warnings on CPUs that support deeper backtrace levels. Currently the builtin-return-address feature of gcc is used to implement deeper backtraces for the debug malloc library. The default value is 0.
Trigger leak detection on exit of the program. The output of the leak detection is sent to the file named by this variable.
Enable tracing of all calls to malloc(), free(), calloc(), realloc(), etc. A trace of the various calls is store in the file named by this variable.
Specify the level of checking performed by the MALLOC_CKACCESS option to mallopt().

Reverting to the behavior of Neutrino 6.2

In order to revert to the allocator behavior from QNX Neutrino 6.2, do one of the following:

You can also set both variables to fine-tune the allocator's behavior. The easiest way is to explicitly set the MALLOC_ARENA_CACHE_MAXSZ value to set a cap on the total amount of memory held in the allocator. The MALLOC_ARENA_CACHE_MAXBLK value is more difficult to configure, because arena blocks aren't necessarily the same size, and hence setting the number alone may not give the exact desired behavior.


ANSI, POSIX 1003.1

Cancellation point No
Interrupt handler No
Signal handler No
Thread Yes


Don't use brk() and sbrk() with any other memory functions (such as malloc(), mmap(), and free()). The brk() function assumes that the heap is contiguous; in Neutrino, memory is returned to the system by the heap, causing the heap to become sparse. The Neutrino malloc() function is based on mmap(), and not on brk().

In QNX 4, nothing is allocated when you malloc() 0 bytes. Be careful if your code is ported between QNX 4 and QNX Neutrino.