- C dynamic memory allocation
-
C Standard Library - Data types
- Character classification
- Strings
- Mathematics
- File input/output
- Date/time
- Localization
- Memory allocation
- Program control
- Miscellaneous headers:
C dynamic memory allocation refers to performing dynamic memory allocation in the C via a group of functions in the C standard library, namely
malloc
,realloc
,calloc
andfree
.[1][2][3]The C++ programming language includes these functions for backwards compatibility; its use in C++ has been largely superseded by operators
new
andnew[]
.[4]Many different implementations of the actual memory allocation mechanism, used by
malloc
, are available. Their performance varies in both execution time and required memory.Contents
Rationale
The C programming language manages memory statically, automatically, or dynamically. Static-duration variables are allocated in main (fixed) memory and persist for the lifetime of the program; automatic-duration variables are allocated on the stack and come and go as functions are called and return. For static-duration and, before C99 (which allows variable-length automatic arrays[5]), automatic-duration variables, the size of the allocation is required to be compile-time constant. If the required size is not known until run-time (for example, if data of arbitrary size is being read from the user or from a disk file), then using fixed-size data objects is inadequate.
The lifetime of allocated memory is also a concern. Neither static- nor automatic-duration memory is adequate for all situations. Automatic-allocated data cannot persist across multiple function calls, while static data persists for the life of the program whether it is needed or not. In many situations the programmer requires greater flexibility in managing the lifetime of allocated memory.
These limitations are avoided by using dynamic memory allocation in which memory is more explicitly (but more flexibly) managed, typically, by allocating it from the heap, an area of memory structured for this purpose. In C, the library function
malloc
is used to allocate a block of memory on the heap. The program accesses this block of memory via a pointer thatmalloc
returns. When the memory is no longer needed, the pointer is passed tofree
which deallocates the memory so that it can be used for other purposes.Some platforms provide library calls which allow run-time dynamic allocation from the C stack rather than the heap (e.g. Unix
alloca()
,[6] Microsoft Windows CRTL'smalloca()
[7]). This memory is automatically freed when the calling function ends. The need for this is lessened by changes in the C99 standard, which added support for variable-length arrays of block scope having sizes determined at runtime.Overview of functions
The C dynamic memory allocation functions are defined in
stdlib.h
header (cstdlib
header in C++).[1]malloc
- C/C++ - allocates the specified number of bytesrealloc
- C/C++ - increases the size of the specified block of memory. Reallocates it if neededcalloc
- C/C++ - allocates the specified number of bytes and initializes them to zerofree
- C/C++ - releases the specified block of memory back to the system
Usage example
The standard method of creating an array of 10 int objects:
int array[10];
However, if one wishes to allocate a similar array dynamically, the following code could be used:
/* Allocate space for an array with ten elements of type int. */ int *ptr = (int *) malloc(10 * sizeof (int)); if (ptr == NULL) { /* Memory could not be allocated, the program should handle the error here as appropriate. */ } else { /* Allocation succeeded. Do something. */ free(ptr); /* We are done with the int objects, and free the associated pointer. */ ptr = NULL; /* The pointed-to-data must not be used again, unless re-assigned by using malloc again. */ }
malloc
returns a null pointer to indicate that no memory is available, or that some other error occurred which prevented memory being allocated.Type safety
malloc
returns a void pointer (void *
), which indicates that it is a pointer to a region of unknown data type. The lack of a specific pointer type returned frommalloc
is type-unsafe behaviour:malloc
allocates based on byte count but not on type. This distinguishes it from the C++ new operator that returns a pointer whose type relies on the operand. (see C Type Safety).One may "cast" (see type conversion) this pointer to a specific type:
int *ptr; ptr = malloc(10 * sizeof (*ptr)); // Without a cast ptr = (int*)malloc(10 * sizeof (int)); // With a cast
There are advantages and disadvantages to performing such a cast.
Advantages to casting
- Including the cast allows for compatibility with C++, which does require the cast to be made.
- The cast allows for older versions of
malloc
that originally returned achar *
.[8]
Disadvantages to casting
- Under the ANSI C standard, the cast is redundant.
- Adding the cast may mask failure to include the header
stdlib.h
, in which the prototype formalloc
is found.[8][9] In the absence of a prototype formalloc
, the standard requires that the C compiler assumemalloc
returns anint
. If there is no cast, a warning is issued when this integer is assigned to the pointer; however, with the cast, this warning is not produced, hiding a bug. On certain architectures and data models (such as LP64 on 64-bit systems, wherelong
and pointers are 64-bit andint
is 32-bit), this error can actually result in undefined behaviour, as the implicitly declaredmalloc
returns a 32-bit value whereas the actually defined function returns a 64-bit value. Depending on calling conventions and memory layout, this may result in stack smashing. This issue is not present in modern compilers, as they uniformly produce warnings that an undeclared function has been used, so a warning will still appear. For example, gcc's default behaviour is to show a warning that reads "incompatible implicit declaration of built-in function" regardless of whether the cast is present or not. - If type of pointer is changed, using cast requires one to fix all code lines where malloc was called
Common errors
The improper use of dynamic memory allocation can frequently be a source of bugs.
Most common errors are as follows:
- Allocation failure. Memory allocation is not guaranteed to succeed. If there's no check for successful allocation implemented, this usually leads to a crash of the program or the entire system.
- Memory leaks. Failure to deallocate memory using
free
leads to buildup of memory that is non-reusable memory, which is no longer used by the program. This wastes memory resources and can lead to allocation failures when these resources are exhausted. - Logical errors. All allocations must follow the same pattern: allocation using
malloc
, usage to store data, deallocation usingfree
. Failures to adhere to this pattern, such as memory usage after call to afree
or before call tomalloc
, callingfree
twice, etc., usually leads to a crash of the program.
Implementations
The implementation of memory management depends greatly upon operating system and architecture. Some operating systems supply an allocator for malloc, while others supply functions to control certain regions of data. The same dynamic memory allocator is often used to implement both
malloc
and the operatornew
in C++[citation needed]. Hence, it is referred to below as the allocator rather thanmalloc
.Heap-based
Implementation of the allocator on IA-32 architectures is commonly done using the heap, or data segment. The allocator will usually expand and contract the heap to fulfill allocation requests.
The heap method suffers from a few inherent flaws, stemming entirely from fragmentation. Like any method of memory allocation, the heap will become fragmented; that is, there will be sections of used and unused memory in the allocated space on the heap. A good allocator will attempt to find an unused area of already allocated memory to use before resorting to expanding the heap. The major problem with this method is that the heap has only two significant attributes: base, or the beginning of the heap in virtual memory space; and length, or its size. The heap requires enough system memory to fill its entire length, and its base can never change. Thus, any large areas of unused memory are wasted. The heap can get "stuck" in this position if a small used segment exists at the end of the heap, which could waste any magnitude of address space, from a few megabytes to a few hundred.
dlmalloc
Doug Lea is the author of a memory allocator called dlmalloc ("Doug Lea's Malloc").
Memory on the heap is allocated as "chunks", an 8-byte aligned data structure which contains a header and usable memory. Allocated memory contains an 8 or 16 byte overhead for the size of the chunk and usage flags. Unallocated chunks also store pointers to other free chunks in the usable space area, making the minimum chunk size 24 bytes.[10]
Unallocated memory is grouped into "bins" of similar sizes, implemented by using a double-linked list of chunks (with pointers stored in the unallocated space inside the chunk).[10]
For requests below 256 bytes (a "smallbin" request), a simple two power best fit allocator is used. If there are no free blocks in that bin, a block from the next highest bin is split in two.
For requests of 256 bytes or above but below the mmap threshold, recent versions of dlmalloc use an in-place bitwise trie algorithm. If there is no free space left to satisfy the request, dlmalloc tries to increase the size of the heap, usually via brk system call.
For requests above the mmap threshold (a "largebin" request), the memory is always allocated using the mmap system call. The threshold is usually 256 KB[11] The mmap method averts problems with huge buffers trapping a small allocation at the end after their expiration, but always allocates an entire page of memory, which on many architectures is 4096 bytes in size.[12]
FreeBSD's and NetBSD's jemalloc
Since FreeBSD 7.0 and NetBSD 5.0, the old
malloc
implementation (phkmalloc) was replaced by jemalloc, written by Jason Evans. The main reason for this was a lack of scalability of phkmalloc in terms of multithreading. In order to avoid lock contention, jemalloc uses separate "arenas" for each CPU. Experiments measuring number of allocations per second in multithreading application have shown that this makes it scale linearly with the number of threads, while for both phkmalloc and dlmalloc performance was inversely proportional to the number of threads.[13]OpenBSD's malloc
OpenBSD's implementation of the
malloc
function makes use ofmmap
. For requests greater in size than one page, the entire allocation is retrieved usingmmap
; smaller sizes are assigned from memory pools maintained bymalloc
within a number of "bucket pages," also allocated withmmap
. On a call tofree
, memory is released and unmapped from the process address space usingmunmap
. This system is designed to improve security by taking advantage of the address space layout randomization and gap page features implemented as part of OpenBSD'smmap
system call, and to detect use-after-free bugs—as a large memory allocation is completely unmapped after it is freed, further use causes a segmentation fault and termination of the program.Hoard's malloc
The Hoard memory allocator is an allocator whose goal is scalable memory allocation performance. Like OpenBSD's allocator, Hoard uses
mmap
exclusively, but manages memory in chunks of 64 kilobytes called superblocks. Hoard's heap is logically divided into a single global heap and a number of per-processor heaps. In addition, there is a thread-local cache that can hold a limited number of superblocks. By allocating only from superblocks on the local per-thread or per-processor heap, and moving mostly-empty superblocks to the global heap so they can be reused by other processors, Hoard keeps fragmentation low while achieving near linear scalability with the number of threads.[14]Thread-caching malloc (tcmalloc)
Every thread has local storage for small allocations. For large allocations mmap or sbrk can be used. Tcmalloc has garbage-collection for local storage of dead threads. The TCmalloc is considered to be more than twice as fast as glibc's ptmalloc for multithreaded programs.[15][16]
In-kernel
Operating system kernels need to allocate memory just as application programs do. The implementation of
malloc
within a kernel often differs significantly from the implementations used by C libraries, however. For example, memory buffers might need to conform to special restrictions imposed by DMA, or the memory allocation function might be called from interrupt context.[17] This necessitates amalloc
implementation tightly integrated with the virtual memory subsystem of the operating system kernel.Allocation size limits
The largest possible memory block
malloc
can allocate depends on the host system, particularly the size of physical memory and the operating system implementation. Theoretically, the largest number should be the maximum value that can be held in asize_t
type, which is an implementation-dependent unsigned integer representing the size of an area of memory. The maximum value is 2CHAR_BIT × sizeof(size_t) − 1, or the constantSIZE_MAX
in the C99 standard.See also
References
- ^ a b ISO/IEC 9899:1999 specification. p. 313, § 7.20.3 "Memory management functions". http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf.
- ^ Godse, A.P.; D.A.Godse (2008). Advanced C Programming. p. 6-28: Technical Publications. pp. 400. ISBN 9788184314960.
- ^ Summit, Steve. "C Programming Notes - Chapter 11: Memory Allocation". http://c-faq.com/~scs/cclass/notes/sx11.html. Retrieved 30 October 2011.
- ^ Stroustrup, Bjarne (2008). Programming: Principles and Practice Using C++. 1009, §27.4 Free store: Addison Wesley. pp. 1236. ISBN 978-0-321-54372-1.
- ^ gcc manual on gnu.org accessed at 14 December 2008
- ^ "alloca". Man.freebsd.org. 5 September 2006. http://man.freebsd.org/alloca. Retrieved 18 September 2011.
- ^
malloca()
page on MSDN Visual C++ Developer Center. Accessed on 12 March 2009 - ^ a b FAQ > Explanations of... > Casting malloc on Cprogramming.com accessed at 9 March 2007
- ^ comp.lang.c FAQ list · Question 7.7b on C-FAQ accessed at 9 March 2007
- ^ a b Kaempf, Michel (2001). "Vudo malloc tricks". Phrack (57): 8. http://phrack.org/issues.html?issue=57&id=8&mode=txt. Retrieved 29 April 2009.
- ^ "Malloc Tunable Parameters". GNU. http://www.gnu.org/software/libc/manual/html_node/Malloc-Tunable-Parameters.html. Retrieved 2 May 2009.
- ^ Sanderson, Bruce (12 December 2004). "RAM, Virtual Memory, Pagefile and all that stuff". Microsoft Help and Support. http://support.microsoft.com/kb/555223.
- ^ http://people.freebsd.org/~jasone/jemalloc/bsdcan2006/jemalloc.pdf
- ^ http://www.cs.umass.edu/~emery/pubs/berger-asplos2000.pdf
- ^ http://goog-perftools.sourceforge.net/doc/tcmalloc.html
- ^ Mark Callaghan (18 January 2009). "High Availability MySQL: Double sysbench throughput with TCMalloc". Mysqlha.blogspot.com. http://mysqlha.blogspot.com/2009/01/double-sysbench-throughput-with_18.html. Retrieved 18 September 2011.
- ^ "kmalloc()/kfree() include/linux/slab.h". People.netfilter.org. http://people.netfilter.org/~rusty/unreliable-guides/kernel-hacking/routines-kmalloc.html. Retrieved 18 September 2011.
External links
- Definition of malloc in IEEE Std 1003.1 standard
- The design of the basis of the glibc allocator, by Doug Lea
- The ptmalloc homepage, by Wolfram Gloger
- The Hoard homepage, by Emery Berger
- The nedmalloc homepage, by Niall Douglas
- The jemalloc homepage, by Jason Evans
- TCMalloc homepage, a high-performance malloc developed by Google
- Simple Memory Allocation Algorithms on OSDEV Community
- Hoard: A Scalable Memory Allocator for Multithreaded Applications by Emery Berger
- Scalable Lock-Free Dynamic Memory Allocation by Maged M. Michael
- Inside memory management - The choices, tradeoffs, and implementations of dynamic allocation by Jonathan Bartlett
- Memory Reduction (GNOME) wiki page with lots of information about fixing malloc
- C99 standard draft, including TC1/TC2/TC3
- Some useful references about C
- ISO/IEC 9899 – Programming languages – C
Memory management Manual memory management Virtual memory Hardware Garbage collection ImplementationsBoehm garbage collector • Garbage-first collectorMemory segmentation Memory safety Issues Other Automatic variable • International Symposium on Memory Management • Region-based memory managementCategories:- Memory management
- Memory management software
- C Standard Library
Wikimedia Foundation. 2010.