原型:
void * malloc(size_t size)
返回地址的前面size_t空间存储的是此次分配内存的chunk大小。
chunk大小的规则是:
align(size + sizeof(size_t), 2 * sizeof(size_t))
就是待分配用户空间大小+一个metadata的头大小,然后按照两倍size_t对齐分配。所以:
- 对于32bit系统, sizeof(size_t) == 4,所以两倍地址是8字节对齐。
- 对应64bit系统,sizeof(size_t) == 8,所以两倍地址是16字节对齐。
然后chunk大小的后3bit是标志位,既然chunk大小是固定的必须满足对齐格式,所以这末几位也没有用处才,正好用在其他标记位:
(...size...|A|M|P)
- P: PREV_INUSE : 0x1
- M: IS_MMAPPED: 0x2
- A: NON_MAIN_ARENA: 0x4
用代码测试一下:
void * mymalloc(size_t sz) {
size_t cksz = 0;
void * p= malloc(sz);
//struct malloc_chunk * mc= ((struct malloc_chunk *)((char*)(p) - 2 * sizeof(size_t)));
//cksz = (mc)->size;
cksz = *(size_t *)((unsigned char *)p - sizeof(size_t));
cksz = cksz & ~0x7; // the size's last 3bits are PREV_INUSE|IS_MMAPPED|NON_MAIN_ARENA flag
printf("p=%p, mallocsz=%04d, chunksz=%04d(%02d)\n", p, sz, cksz, cksz-sz);
return p;
}
运行几个例子:
p=0x1881010, mallocsz=0071, chunksz=0080(09)
p=0x1881060, mallocsz=0072, chunksz=0080(08)
p=0x18810b0, mallocsz=0073, chunksz=0096(23)
p=0x1881110, mallocsz=0074, chunksz=0096(22)
p=0x1881170, mallocsz=0075, chunksz=0096(21)
p=0x18811d0, mallocsz=0076, chunksz=0096(20)
p=0x1881230, mallocsz=0077, chunksz=0096(19)
p=0x1881290, mallocsz=0078, chunksz=0096(18)
p=0x18812f0, mallocsz=0079, chunksz=0096(17)
p=0x1881350, mallocsz=0080, chunksz=0096(16)
p=0x18813b0, mallocsz=0081, chunksz=0096(15)
p=0x1881410, mallocsz=0082, chunksz=0096(14)
p=0x1881470, mallocsz=0083, chunksz=0096(13)
p=0x18814d0, mallocsz=0084, chunksz=0096(12)
p=0x1881530, mallocsz=0085, chunksz=0096(11)
- 分配71字节,加上头8字迹,然后align(79, 16)=80
- 分配72字节,加上头8字迹,然后align(80, 16)=80
- 分配73字节,加上头8字迹,然后align(81, 16)=96
...
前面是64bit系统的,chunksz按照对齐是16字节对齐的,而对于32bit系统而言:gcc -m32 ...
,运行结果是:
p=0x9f20008, mallocsz=0071, chunksz=0080(09)
p=0x9f20058, mallocsz=0072, chunksz=0080(08)
p=0x9f200a8, mallocsz=0073, chunksz=0080(07)
p=0x9f200f8, mallocsz=0074, chunksz=0080(06)
p=0x9f20148, mallocsz=0075, chunksz=0080(05)
p=0x9f20198, mallocsz=0076, chunksz=0080(04)
p=0x9f201e8, mallocsz=0077, chunksz=0088(11)
p=0x9f20240, mallocsz=0078, chunksz=0088(10)
p=0x9f20298, mallocsz=0079, chunksz=0088(09)
p=0x9f202f0, mallocsz=0080, chunksz=0088(08)
p=0x9f20348, mallocsz=0081, chunksz=0088(07)
p=0x9f203a0, mallocsz=0082, chunksz=0088(06)
p=0x9f203f8, mallocsz=0083, chunksz=0088(05)
p=0x9f20450, mallocsz=0084, chunksz=0088(04)
p=0x9f204a8, mallocsz=0085, chunksz=0096(11)
- 分配71字节,加上头4字迹,然后align(75, 8)=80
- 分配72字节,加上头4字迹,然后align(76, 8)=80
- 分配73字节,加上头4字迹,然后align(77, 8)=80
...
网友评论