INTERNAL_SIZE_T size_t
#define SIZE_SZ (sizeof(INTERNAL_SIZE_T))
MALLOC_ALIGNMENT MAX (2 * sizeof(INTERNAL_SIZE_T),
__alignof__ (long double))
#define MALLOC_ALIGN_MASK (MALLOC_ALIGNMENT - 1)
struct malloc_chunk {
/* prev_size and size makes the header */
INTERNAL_SIZE_T prev_size; /* Size of previous chunk (if free). */
INTERNAL_SIZE_T size; /* Size in bytes, including overhead. */
struct malloc_chunk* fd; /* double links -- used only if free. */
struct malloc_chunk* bk;
struct malloc_chunk* fd_nextsize; /* double links -- used only if free. */
struct malloc_chunk* bk_nextsize;
};
/* The smallest possible chunk */
#define MIN_CHUNK_SIZE (offsetof(struct malloc_chunk, fd_nextsize))
/* The smallest possible aligned chunk */
#define MINSIZE \
(unsigned long)(((MIN_CHUNK_SIZE+MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK))
/* Convert user request to a usable size */
#define request2size(req) \
(((req) + SIZE_SZ + MALLOC_ALIGN_MASK < MINSIZE) ? \
MINSIZE : \
((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK)
malloc块(struct malloc_chunk
)实际上是2个部分:包含prev_size
(前一个块的大小)和size
(当前块的大小)和正文的头部这是返回给用户的块的一部分。一旦块被释放,用户使用的空间现在被重用来存储
fd
和bk
指针(freelist指针)。
当用户请求内存(malloc(size_t)
)时,首先将用户请求的大小转换为malloc可用大小。规则是malloc块
应该至少有足够的空间来存储头信息和空闲列表指针(当块稍后被释放时),因此,我们有一个最小的
大小为MIN_CHUNK_SIZE
的大小块,但malloc保证块是对齐的,因此最小对齐块的大小为MINSIZE
。
问题出在request2size
宏。通常,要进行转换,根据上面的描述,我们计算出的值
size = (user requested size + the header size (2 * SIZE_SZ))
然后继续进行验证:
if (size < MINSIZE)
final_size = MINSIZE; /* The size is not big enough to make a usable chunk so just round it to MINSIZE */
else
final_size = (size + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK; /* The chunk is big enough to contain the header and free list pointers, we just need to make sure it is aligned */
但request2size
宏中没有发生这种情况。它只会向SIZE_SZ
添加一个req
单元(标题需要2),并在比较前添加MALLOC_ALIGN_MASK
。
我试图理解宏背后的逻辑,但我无法得到它。是否有人可以解释这个宏如何工作(如何填充和对齐块)?
有关详细信息,请查看此github个回购邮件中的ptmalloc2的malloc.c源代码。