1

因此,对于我的一项学校作业,我必须实现自己的内存分配包。我使用一个结构块来表示一个空闲的内存块,并创建一个这些块的列表,显示我的内存堆上的空闲空间在哪里,也称为我的“空闲列表”。下面是我创建的块结构。

 typedef struct block {
    struct block *next;
    struct block *prev;
    int size;
    unsigned char *buffer;
} block;

my_malloc() 实现(见下文)在我的测试下似乎工作正常。

void *my_malloc(int size){
    //if my_malloc has never been called before create the first
    // free block who's data buffer spans the entire heap
    if(!initialized){
        initialized = 1; //Next time, we've already inited
        // Create the first block
            *(block *)head = (block){NULL, NULL, 0, NULL};
            block *p = (block *)head;
            //try setting size to 128KB and point buffer properly
            p->size = 1024*128;
            p->buffer = p+ 1;
            printf("Address of buffer is %p\n", p->buffer);
            // set the program break 
            brk(head + (sizeof(block)+p->size));

    }
    block *p = (block *)head;   //point to the head, we don't want to move the head...
    // find the appropriate free block and check for nullity
    block *selected = find_block(size);
    if(selected==NULL){
        printf("Had no space first time around!\n");
        //go to the end of the free list
        while(p->next!=NULL){
            p=p->next;
        }
        // increase it's size by 128KB
        p->size=p->size+(128*1024);
        // move the program break by additional 128KB
        sbrk(128*1024);
        //now the last free block has enough space, so make it the selected block
        selected=p;
    }
    block *new_block; // new block we will create
    // if the block we have to allocate is pointed by head, we need a new
    // head
    if ((block *)selected==(block *)head){
        //shift head
        head = selected->buffer+ size;
        //Create a new block there, it wil be our new head and we don't return it
        *(block *)head = (block){NULL, NULL, 0, NULL};
        block *new_block = (block *)head;
        new_block->prev = selected->prev;
        new_block->next = selected->next;
        new_block->size = selected->size-size;
        new_block->buffer = new_block +1;
        printf("The split new_block->buffer points to %p\n", new_block->buffer);
        //return the pointer to original head, not the new one.
        total_malloced=+size;
        return selected->buffer;
    }
    // The selected node is not the head so we don't move the head
    else{
        new_block = selected->buffer+size;
        new_block->prev = selected->prev;
        new_block->next = selected->next;
        new_block->size = selected->size-size;
        new_block->buffer = new_block +1;
        //remove that selected block from the free list
        (selected->prev)->next=new_block;
        total_malloced=+size;
        return selected->buffer;
    }

}

将返回的 my_malloc 指针发送到 my_free() 之类的方法时会出现此问题。

void my_free(void *ptr) {
    printf("Dummy instruct.\n");
}

我收到以下错误:

*** glibc detected *** ./myMalloc: munmap_chunk(): invalid pointer: 0x0804a17e ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x75ee2)[0xb7e7cee2]
/lib/i386-linux-gnu/libc.so.6(+0x765c5)[0xb7e7d5c5]
./myMalloc[0x80485b1]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb7e204d3]
./myMalloc[0x8048401]
======= Memory map: ========
08048000-08049000 r-xp 00000000 00:3d 8557227    /home/2009/gkrink/os/myMalloc
08049000-0804a000 r--p 00000000 00:3d 8557227    /home/2009/gkrink/os/myMalloc
0804a000-0804b000 rw-p 00001000 00:3d 8557227    /home/2009/gkrink/os/myMalloc
0804b000-0808c000 rw-p 00000000 00:00 0          [heap]
b7e06000-b7e07000 rw-p 00000000 00:00 0 
b7e07000-b7faa000 r-xp 00000000 00:11 4370765    /lib/i386-linux-gnu/libc-2.15.so
b7faa000-b7fab000 ---p 001a3000 00:11 4370765    /lib/i386-linux-gnu/libc-2.15.so
b7fab000-b7fad000 r--p 001a3000 00:11 4370765    /lib/i386-linux-gnu/libc-2.15.so
b7fad000-b7fae000 rw-p 001a5000 00:11 4370765    /lib/i386-linux-gnu/libc-2.15.so
b7fae000-b7fb1000 rw-p 00000000 00:00 0 
b7fbb000-b7fd7000 r-xp 00000000 00:11 6829467    /lib/i386-linux-gnu/libgcc_s.so.1
b7fd7000-b7fd8000 r--p 0001b000 00:11 6829467    /lib/i386-linux-gnu/libgcc_s.so.1
b7fd8000-b7fd9000 rw-p 0001c000 00:11 6829467    /lib/i386-linux-gnu/libgcc_s.so.1
b7fd9000-b7fdd000 rw-p 00000000 00:00 0 
b7fdd000-b7fde000 r-xp 00000000 00:00 0          [vdso]
b7fde000-b7ffe000 r-xp 00000000 00:11 4370778    /lib/i386-linux-gnu/ld-2.15.so
b7ffe000-b7fff000 r--p 0001f000 00:11 4370778    /lib/i386-linux-gnu/ld-2.15.so
b7fff000-b8000000 rw-p 00020000 00:11 4370778    /lib/i386-linux-gnu/ld-2.15.so
bffdf000-c0000000 rw-p 00000000 00:00 0          [stack]
Aborted

这是我的测试功能:

void main(void){
    printf("Testing initiated...\n");
    printf("head is located at %p\n\n", head);
    void * tester;
    printf("mallocing 100...\n");
    tester = my_malloc(100);
    printf("The allocated memory starts at %p\n", tester);
    printf("mallocing 150...\n");
    tester=my_malloc(150);
    printf("The allocated memory starts at %p\n", tester);
    printf("head is located at %p\n\n", head);
    printf("brk is firstly located at %p\n", sbrk(0));
    printf("mallocing 10...");
    tester=my_malloc(10);
    printf("The allocated memory starts at %p\n", tester);
    printf("brk is still at %p\n", sbrk(0));
    free(tester);
}

并且没有将返回的 my_malloc() 指针发送到 my_free() 我得到正确的输出,例如:

测试已启动...头部位于 0x804a054

mallocing 100... buffer 的地址是 0x804a064 split new_block->buffer 指向 0x804a0d8 分配的内存从 0x804a064 mallocing 150... split new_block->buffer 指向 0x804a17e 分配的内存从 0x804a0d8 开始 head 位于 0x804a16e

brk 首先位于 0x806a064 mallocing 10...拆分的 new_block->buffer 指向 0x804a198 分配的内存从 0x804a17e 开始 brk 仍然在 0x806a064

为什么我不能像那样发送指向另一个函数的指针?

4

1 回答 1

4

如果这是实际代码,则您调用的是标准库free而不是您自己的版本:

free(tester);

将指针传递给您尚未分配的内存malloc肯定不会做好事。

于 2013-03-26T17:21:07.413 回答