lcc之内存分配

现在感觉这本书有些地方没有说透,如果自己的理解能力与基础知识够强的话,理解起来还好,如果不行的话,某些地方理解起来会相当的头疼。

现在来说说内存管理。当初看这一章的时候很快就过去了,感觉很多地方很好理解,当看到后面看不下去时,从头再仔细看时,发现当时很多没有注意到的细节问题。

在该书中图2-1我一直觉得这个图画错了,最后发现是我想当然了,其实这个图很正确,只是我没有理解正确。

文中把内存分成了三个大块。

这first仅仅表示这三块的头,即开始的地方, static struct block  first[] = {  { NULL },  { NULL },  { NULL } }, 每一个大块有若干block连接起来

static struct block  *arena[] = { &first[0], &first[1], &first[2] };  arena代表每个大块的尾部,从头到尾中间的任何一块即使有空闲空间也不使用,这些空间被浪费了。

在上面的初始化中arena指向first中的各个项。

具体情况详见图2-1,其中另外一点需要注意的是f每一大块的第一个block中的avail和limit都是NULL表示头指针。

下面解释下allocate()函数。

简要说下步骤,首先从freeblock中开始找,freeblock是共享的,三个大块都可以从中来获取可分配的block,如果在freeblock中没有找到足够大小的block,于是就分配一个新的block,如果找到了足够大的block,则用该block。

void *allocate(n, a) unsigned long n; unsigned a; {
	struct block *ap;

	assert(a < NELEMS(arena));
	assert(n > 0);
	ap = arena[a];//此时ap指向大块a中的最后一个block
	n = roundup(n, sizeof (union align));
	//下面这段循环好阴险,先从freeblock中找,找不到再分配,感觉写的不太好,如果把else移出来就好理解多了
	while (n > ap->limit - ap->avail) 
	{
         //这里的freeblock是共享的,三个大的块共写freeblock。 if ((ap->next = freeblocks) != NULL) {    freeblocks = freeblocks->next; ap = ap->next;//指向freeblock中的block } else { unsigned m = sizeof (union header) + n + 10*1024; ap->next = malloc(m);//malloc return a address of the memory ap = ap->next; if (ap == NULL) { error("insufficient memory\n"); exit(1); } ap->limit = (char *)ap + m; }
      
  
          //经过上面的if和else已经得到了满足大小的内存block(不论是从freeblock中分配得到的还是新分配的)      ap->avail = (char *)((union header *)ap + 1); ap->next = NULL; arena[a] = ap; } ap->avail += n; return ap->avail - n; }

 上面还有一个疑问,first代表头,arena代表尾,当分配一个block时,是怎么把若干block通过next联系起来的。

posted on 2014-07-07 11:19  追寻前人的脚步  阅读(260)  评论(0编辑  收藏  举报

导航