glibc检测到无效指针

时间:2013-03-26 17:15:07

标签: c pointers memory-management

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

 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(),我会得到正确的输出,例如:

  

测试已启动... head位于0x804a054

     

mallocing 100 ...缓冲区的地址是0x804a064分割   new_block->缓冲区指向0x804a0d8分配的内存从...开始   0x804a064 mallocing 150 ...拆分new_block->缓冲区指向   0x804a17e分配的内存从0x804a0d8头开始位于   0x804a16e

     

brk首先位于0x806a064 mallocing 10 ...分裂   new_block->缓冲区指向0x804a198分配的内存从   0x804a17e brk仍在0x806a064

为什么我不能发送指向其他函数的指针?

1 个答案:

答案 0 :(得分:4)

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

free(tester);

将指针传递给尚未分配malloc的内存,绝对不会有好处。