malloc is a function for allocating memory dynamically in the C programming language.
Memory allocation in C
There are four functions commonly associated with dynamic memory allocation in C. They were formerly part of malloc.h but are now part of stdlib.h:
void *malloc(size_t size)
Allocate size bytes of memory. Returns a pointer to the allocated memory if memory could be allocated successfully; otherwise, a NULL pointer is returned.
void *calloc(size_t elements, size_t bytes)
Allocate elements of size bytes each and initialise them to zero. Returns a pointer to the first element of the allocated array, or NULL if an error occurred.
void *realloc(void *pointer, size_t bytes)
If bytes is greater than the existing size of pointer, then allocate additional memory to compensate. Returns a pointer to the new portion of memory. If bytes is less than the existing size, then free the difference. Returns pointer, or NULL if an error occurred.
void free(void *pointer)
Free the memory that has been allocated to pointer.
Usage example
The standard method of creating an array of ten integers:
int array[10];
Alternatively we can create a pointer to the first element of the array. There following, the pointer will reference the array.
int array[10];
int *ptr;
ptr = &array[0]; /* the & operator returns the memory address the first element (0) of the array */
/* ptr[n] and array[n] are equivalent */
Pointers become more useful with dynamic memory allocation. To allocate an array of variable size, the following code can be used:
#include <stdlib.h>
int *ptr;
ptr = malloc(sizeof(int) * n);
if (ptr != NULL)
{
/* ptr refers to a region of memory that is large
enough to hold n items of type int */
}
A simpler method for the above that also guarantees that all items will be set to zero:
#include <stdlib.h>
int *ptr;
ptr = calloc(n, sizeof(int));
The size of the memory allocation can also be changed at any time using the following method:
ptr = realloc(ptr, sizeof(int) * m)
/* ptr now refers to a region of memory that can hold m items of type int */
The following method can be used to free the memory associated with ptr:
free(ptr);
Common errors
Some programmers find that malloc and related functions in C can be a frequent source of bugs.
Allocation failure
malloc is not guaranteed to succeed — if there is no virtual memory available, or the program has exceeded the amount of virtual memory it is allowed to reference, malloc will return a NULL pointer. Depending on the design of the operating system and the C standard library, this may happen with some frequency in production environments. Therefore, a well-written program should handle this situation. Unfortunately, many programs do not, and will crash if malloc fails. One reason why malloc failures are often ignored is that recovering from the error can be difficult.
Memory leaks
The return value of malloc, calloc, and realloc must be passed to the free function so that it can be released. If this is not done, the allocated memory is not released until the process exits — in other words, a memory leak will occur.
Double free
When a pointer has been passed to free it can still be used, but it now references a region of memory with undefined content. For example:
int *ptr = malloc(sizeof(int));
free(ptr);
*ptr = 0; /* undefined behavior */
Problems of this kind can result in unpredictable program behavior — after the memory has been freed, the system may reuse that memory region for storage of unrelated data. So writing through a pointer to a deallocated region of memory may result in overwriting another piece of data somewhere else in the program — which may cause data corruption, or crash the program at some future point in time.
A particularly bad example of this problem is if the same pointer is passed to free twice.
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 operator new in C++. Hence, we will call this the allocator rather than malloc.
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 system RAM, from a few megabytes to a few hundred.
The glibc allocator
The GNU C library, glibc, uses both brk and mmap on the Linux operating system. The brk system call will change the size of the heap to be larger or smaller as needed; while the mmap system call will be used when extremely large segments are allocated. The heap method suffers the same flaws as any other, while the mmap method may avert problems with huge buffers trapping a small allocation at the end after their expiration.
The mmap method has its own flaws. It always allocates a segment by mapping pages. Only one set of mapped pages exists for each allocated segment. Mapping a single byte will use an entire page, usually 4096 bytes, on IA-32; however, huge pages are 4MiB, 1024 times larger, and so this method could be particularly devastating if userspace uses all huge pages. The advantage to the mmap method is that when the segment is freed, the memory is returned to the system immediately.
See also
External links