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.
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.
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_BANDCONFIG
- If you specify the band configurations, you also have to set this
environment variable to 1 to ensure that your configurations are picked.
- 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 Neutrino 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().
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:
- Set MALLOC_ARENA_CACHE_MAXBLK to 0, which results in no
caching of arenas.
Or:
- Set MALLOC_ARENA_CACHE_MAXSZ to 400000, which limits the
total caching of the blocks to 400000 bytes.
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.
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 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.