随笔

记录,分享,然后享受生活。

0%

申请堆内存的相关代码

mm.cview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/* 
* mm_malloc - Allocate a block with at least size bytes of payload
*/
/* $begin mmmalloc */
void *mm_malloc(size_t size)
{
size_t asize; /* Adjusted block size */
size_t extendsize; /* Amount to extend heap if no fit */
char *bp;

/* $end mmmalloc */
if (heap_listp == 0){
mm_init();
}
/* $begin mmmalloc */
/* Ignore spurious requests */
if (size == 0)
return NULL;

/* Adjust block size to include overhead and alignment reqs. */
if (size <= DSIZE) //line:vm:mm:sizeadjust1
asize = 2*DSIZE; //line:vm:mm:sizeadjust2
else
asize = DSIZE * ((size + (DSIZE) + (DSIZE-1)) / DSIZE); //line:vm:mm:sizeadjust3

/* Search the free list for a fit */
if ((bp = find_fit(asize)) != NULL) { //line:vm:mm:findfitcall
place(bp, asize); //line:vm:mm:findfitplace
return bp;
}

/* No fit found. Get more memory and place the block */
extendsize = MAX(asize,CHUNKSIZE); //line:vm:mm:growheap1
if ((bp = extend_heap(extendsize/WSIZE)) == NULL)
return NULL; //line:vm:mm:growheap2
place(bp, asize); //line:vm:mm:growheap3
return bp;
}
/* $end mmmalloc */

下面这块代码用到了整型数的除法操作会抹去小数的特点。

1
asize = DSIZE * ((size + (DSIZE) + (DSIZE-1)) / DSIZE);

其目的是为了申请一块按 DSIZE 字节大小对齐的内存,正向推导是没问题的,不过我想知道为啥会想到这样去写?

仔细想了想,用小学的除法知识就能很好的解释这段代码,当size 能被 DSIZE 整除时,size+DSIZE 除以 DSIZE 的余数是 0 ,这时的 asize 就是 size + DSIZE , 而当size 不能被 DSIZE 整除时,size+DSIZE 除以 DSIZE 的余数范围一定是落在 [1, DSIZE-1] 之间,这样一来余数加上 DSIZE-1 的范围就落在了 [DSIZE, 2DSIZE-2] 之间, 这个范围去除以 DSIZE 的结果必定是 1 ,此时的 asize 就是 size+1+DSIZE

也就达到来了代码的目的,按 DSIZE 字节对齐方式申请内存大小。