malloc()

Allocate memory

Synopsis:

#include <stdlib.h>

void* malloc( size_t size );

Arguments:

size
The number of bytes to allocate.

Library:

libc

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

Description:

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

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.

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.

The heap is protected by such security measures as address space layout randomization (ASLR), which randomizes the stack start address and code locations in executables and libraries, and heap cookies.

Returns:

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

Errors:

ENOMEM
Not enough memory.
EOK
No error.

Examples:

#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:

MALLOC_ARENA_CACHE_MAXBLK
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.
MALLOC_ARENA_CACHE_MAXSZ
The maximum size of the arena cache.
MALLOC_ARENA_SIZE
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:

malloc(100);
malloc(200);
  

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.

MALLOC_FREE_LIFO
If set, malloc() changes the free queueing strategy from the default (FIFO) to LIFO.
MALLOC_MEMORY_HOLD
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.
MALLOC_MMAP_NOZERO
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:

MALLOC_BAND_CONFIG_STR
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:

s
The band size.
n
The number of items.
p
The preallocation value, which can be zero.
MALLOC_MEMORY_PREALLOCATE
Preallocate and populate the arena cache by setting this environment variable to a value that specifies the size of the total arena cache.
MALLOC_OPTIONS
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 BlackBerry 10 OS Programmer's Guide.

Debugging

The debug malloc library also uses these environment variables:

MALLOC_INITVERBOSE
Enable some initial verbose output regarding other variables that are enabled.
MALLOC_BTDEPTH
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.
MALLOC_TRACEBT
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.
MALLOC_DUMP_LEAKS
Trigger leak detection on exit of the program. The output of the leak detection is sent to the file named by this variable.
MALLOC_TRACE
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.
MALLOC_CKACCESS_LEVEL
Specify the level of checking performed by the MALLOC_CKACCESS option to mallopt().

Classification:

ANSI, POSIX 1003.1

Safety:  
Cancellation point No
Interrupt handler No
Signal handler No
Thread Yes

Caveats:

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 BlackBerry 10 OS, memory is returned to the system by the heap, causing the heap to become sparse. The BlackBerry 10 OS malloc() function is based on mmap(), and not on brk().

Last modified: 2013-12-23

comments powered by Disqus