我的malloc没有正确更新堆

时间:2017-11-08 06:33:45

标签: c

我试图实现自己的malloc,然后通过转储堆来测试它,看看我能够完成什么。它编译得很好但是当我运行它时,我得到了

的输出
head->[1:0:8]->NULL
this is a test program

之后它会立即崩溃。它看起来像我实现malloc的方式,它能够为* this和*分配空间,但这就是全部。任何人都有任何想法,为什么会这样?

我的main.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>


#define MALLOC(n) my_malloc(n)
#define DUMP_HEAP() dump_heap()
void* my_malloc(int);

int main()
{
  char *this = MALLOC(5);
  char *is = MALLOC(3);
  char *a = MALLOC(2);
  char *test = MALLOC(5);
  DUMP_HEAP();

  strcpy(this, "this");
  strcpy(is, "is");
  strcpy(a, "a");
  strcpy(test, "test");
  strcpy(program, "program");
  printf("%s %s %s %s %s\n", this, is, a, test, program);
  DUMP_HEAP();

  return 0;
}

我的malloc.c

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <assert.h>

struct Block 
{
    int occ;             
    int size;            
    struct Block *prev;   
    struct Block *next;  
};

static struct Block *head = NULL; 

void *my_malloc(int size)
{
    void *pointer;
    pointer = (void*)sbrk(size);
    if(head == NULL)
    {
            head = pointer;
            head->occ = 1;
            head->prev=NULL;
            head->next=NULL;
            head->size = size;

            return (void*)head+sizeof(struct Block);
    }
    else
    {
            struct Block* new ;
            new = pointer;
            head->next = new;
            new->size = size;
            new->occ = 1;
            new->prev = head;
            new->next = NULL;
            head = new;

            return (void*)new+sizeof(struct Block);
    }
}

void dump_heap()
{
  struct Block *cur;
  printf("head->");
  for(cur = head; cur != NULL; cur = cur->next) 
  {
    printf("[%d:%d:%d]->", cur->occ, (char*)cur - (char*)head, cur->size);
    assert((char*)cur >= (char*)head && (char*)cur + cur->size < (char*)sbrk(0));
    if(cur->next != NULL) assert(cur->next->prev == cur); 
  }
  printf("NULL\n");
}

1 个答案:

答案 0 :(得分:2)

在向系统询问内存时,您没有考虑Block结构的大小。

比较这一行:

pointer = (void*)sbrk(size);

以后如何尝试对结构进行说明:

return (void*)head+sizeof(struct Block);

您应该考虑sbrk呼叫中Block的大小:

pointer = (void*)sbrk(size + sizeof(struct Block));

另外,正如已经指出的那样,你不应该在void*上做指针算术。因此,您的返回语句应该保持head指针未被发现,只需将1添加到块大小的帐户中:

return (void*)(head + 1);

另外,经过进一步讨论,很明显head被用作链表的尾部。这引入了dump_heap中的错误。您可能希望将head重命名为tail并维护一个正确的head,该malloc仅在NULL之前RNFS.ls(PATH). 更改{。}}。