大家应该都比较熟悉这一点:malloc分配的内存一定大于用户指定的大小!而且很多人也问过这样的问题:到底大多少?以及实际上malloc到底分配了多少?
我们知道这个大小一定在某个“神奇”地方记录着,但是就像自己的“思维”一样,你确无法感知!不过,这是错觉,只是我们习惯了只使用,而没有深入剖析源码,在这里我将揭开这个面纱,去掉其透明化!
声明:源码基于GNU glib库的2.7版本的malloc目录下相关文件
再声明:不同的C库实现方式不一定一样,这里是glib库,如果你想知道window的或者其他,请Alt + F4
摘要
malloc.c中开篇注释表达一种观点:这里的算法不一定是最好的,但是应该是普遍适用的
此文件包含的函数实现,以及Vital statistics,Alignment,Minimum/Maximum allocated size,最后注明:我是线程安全的,骚年call me!@_@
/*
* Why use this malloc?
This is not the fastest, most space-conserving, most portable, or
most tunable malloc ever written. However it is among the fastest
while also being among the most space-conserving, portable and tunable.
Consistent balance across these factors results in a good general-purpose
allocator for malloc-intensive programs.
The main properties of the algorithms are:
* For large (>= 512 bytes) requests, it is a pure best-fit allocator,
with ties normally decided via FIFO (i.e. least recently used).
* For small (<= 64 bytes by default) requests, it is a caching
allocator, that maintains pools of quickly recycled chunks.
* In between, and for combinations of large and small requests, it does
the best it can trying to meet both goals at once.
* For very large requests (>= KB by default), it relies on system
memory mapping facilities, if supported.
For a longer but slightly out of date high-level description, see
http://gee.cs.oswego.edu/dl/html/malloc.html
You may already by default be using a C library containing a malloc
that is based on some version of this malloc (for example in
linux). You might still want to use the one in this file in order to
customize settings or to avoid overheads associated with library
versions.
* Contents, described in more detail in "description of public routines" below.
Standard (ANSI/SVID/...) functions:
malloc(size_t n);
calloc(size_t n_elements, size_t element_size);
free(void* p);
realloc(void* p, size_t n);
memalign(size_t alignment, size_t n);
valloc(size_t n);
mallinfo()
mallopt(int parameter_number, int parameter_value)
Additional functions:
independent_calloc(size_t n_elements, size_t size, void* chunks[]);
independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]);
pvalloc(size_t n);
cfree(void* p);
malloc_trim(size_t pad);
malloc_usable_size(void* p);
malloc_stats();
* Vital statistics:
Supported pointer representation: 4 or 8 bytes
Supported size_t representation: 4 or 8 bytes
Note that size_t is allowed to be 4 bytes even if pointers are 8.
You can adjust this by defining INTERNAL_SIZE_T
Alignment: 2 * sizeof(size_t) (default)
(i.e., 8 byte alignment with 4byte size_t). This suffices for
nearly all current machines and C compilers. However, you can
define MALLOC_ALIGNMENT to be wider than this if necessary.
Minimum overhead per allocated chunk: 4 or 8 bytes
Each malloced chunk has a hidden word of overhead holding size
and status information.
Minimum allocated size: 4-byte ptrs: 16 bytes (including 4 overhead)
8-byte ptrs: 24/32 bytes (including, 4/8 overhead)
When a chunk is freed, 12 (for 4byte ptrs) or 20 (for 8 byte
ptrs but 4 byte size) or 24 (for 8/8) additional bytes are
needed; 4 (8) for a trailing size field and 8 (16) bytes for
free list pointers. Thus, the minimum allocatable size is
16/24/32 bytes.
Even a request