第七章

7-1 修改程序清单7-1中的程序,在每次malloc后打印program break 的值。指定一个较小的内存分配尺寸,观察现象,证明的每次malloc后program break分配了超过所需的内存区域。

我们可以通过一个更简单的程序来实现观察所需的功能。

#include <unistd.h>
#include <malloc.h>

int main(void){
    printf("now : %10p\n", sbrk(0));
    char * a;
    for (int i = 0; i<10; i++)
    {   
        a = malloc(50000);
        printf("%d : %10p\n",i, sbrk(0));
    }
}

运行程序输出如下:

now : 0xaf060fc000
0 : 0xaf0611d000
1 : 0xaf0611d000
2 : 0xaf06141000
3 : 0xaf06141000
4 : 0xaf06141000
5 : 0xaf06166000
6 : 0xaf06166000
7 : 0xaf06166000
8 : 0xaf0618b000
9 : 0xaf0618b000

我们可以看到每次实际上边界分配了空间大于我们所需的空间。

7-2 实现malloc()和free()。

根据课本可以知道,malloc和free是对堆操作的包装,也就是brk函数的包装,在堆空间进行的数据结构的操作。下面是一个简单实现:

#include <unistd.h>
#include <stdio.h>
#include <string.h>

typedef struct mallocBlock{
    struct mallocBlock *before;
    int size;
    int use;
} mb;

static mb * mb_last = NULL;

void * my_malloc(int size){
    mb * mbp;

    //将mbp放置在一个可以容纳下的空间的第一个空块上
    for(mbp = mb_last; mbp != NULL; mbp = mbp->before){
        if(mbp->use == 0 && mbp->size >= size){
            break;
        }
    }

    //如果没有找到这样的块,那么mbp就是链表的最后一个指针是 NULL
    //此时我们要在边界处加上一个新块
    if(mbp == NULL){
        mbp = sbrk(sizeof(mb) + size);
        if (mbp ==(void *) -1) return (void *)0;
        mbp->size = size;
        mbp->before = mb_last;
        mb_last = mbp;
    }
    //将该块记为1标识已经使用。
    mbp->use = 1;
    return mbp + 1;
}

int my_free(void * p){
    if(p == NULL) return 0;
    mb * mbp = (mb *)p - 1;
    mbp->use = 0;
    return 0;
}

int main(void)  
{  
    char * a = my_malloc(1);
    char * b = my_malloc(2);
    char * c = my_malloc(3);
    my_free(a);
    my_free(b);
    my_free(c);
    printf("%p,%p,%p\n",a,b,c);
    b = my_malloc(1);
    printf("%p,%p,%p\n",a,b,c);
    return 0; 
}

这里的malloc实现是和课本实现基本一致,但是没有对大块内存的再分配进行切割。另外,free函数仅仅是将该块标记为可重用而已,并没有对多余空闲的堆进行释放。不过基本上可以满足实现。

在我的电脑上,实现了完整版的free函数,但是在运行过程中,free函数的brk函数会出现异常,导致段错误,尽管检查了brk函数所释放的堆的位置是合法的,但是仍然出错,并且,sbrk所返回的虚拟内存的位置不是连续的,这个和课本上所述有些区别,不清楚是什么原因导致的。

results matching ""

    No results matching ""