c - glibc 检测到无效指针

标签 c pointers memory-management

<分区>

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

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

Testing initiated... head is located at 0x804a054

mallocing 100... Address of buffer is 0x804a064 The split new_block->buffer points to 0x804a0d8 The allocated memory starts at 0x804a064 mallocing 150... The split new_block->buffer points to 0x804a17e The allocated memory starts at 0x804a0d8 head is located at 0x804a16e

brk is firstly located at 0x806a064 mallocing 10...The split new_block->buffer points to 0x804a198 The allocated memory starts at 0x804a17e brk is still at 0x806a064

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

最佳答案

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

free(tester);

将指针传递给您尚未使用 malloc 分配的内存肯定不会有任何好处。

关于c - glibc 检测到无效指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15643375/

相关文章:

c - 为什么这个带有指针的 for 循环不会去任何地方?

c++ - 什么是 “memory stomp” ?

java - jvisualvm 无法与 eclipse 一起使用

c - Linux 编译简单的程序以在 x86 和 x64 上运行

java - 声明一个变量但不初始化它会提高性能吗?

C:结构初始化数组的嵌套大括号如何工作?

c - 二维字符数组

c - 为什么我可以分配一个局部变量并对其进行读取,但如果我尝试在结构中分配一个指针并读取它,则会出现段错误?

C错误: Expected Unqualified-id Before '{' Token

objective-c - 使用点语法设置保留属性时使用自动释放?