自定义malloc()中的无限循环

自定义malloc()中的无限循环,c,memory,dynamic,allocation,C,Memory,Dynamic,Allocation,我试图在C中实现自己的malloc()函数,但我面临这个问题。前两个分配的地址是正确的,但之后,它不会显示其他地址。我的意思是,它陷入了一个无限循环。但是,如果我删除条件&&ptr->size>BLK_size,它似乎会起作用。所以,问题是,为什么这个条件会破坏代码?除了消除该条件外,如何通过其他方式解决这一问题 这是我的密码 /* Author : Singh*/ typedef struct block_header { unsigned int size : 29,

我试图在C中实现自己的
malloc()
函数,但我面临这个问题。前两个分配的地址是正确的,但之后,它不会显示其他地址。我的意思是,它陷入了一个无限循环。但是,如果我删除条件
&&ptr->size>BLK_size
,它似乎会起作用。所以,问题是,为什么这个条件会破坏代码?除了消除该条件外,如何通过其他方式解决这一问题

这是我的密码

/* Author : Singh*/

typedef struct block_header {
    unsigned int size : 29,
                 zero : 2,
                alloc : 1;
} block_header;

//macros
#define HEADER_BLK_SIZE sizeof(block_header) // 4 bytes header
#define ALIGNED_PAYLOAD_SIZE (((((size)-1)>>2)<<2)+4) //to align the payload
#define BLK_SIZE HEADER_BLK_SIZE + ALIGNED_PAYLOAD_SIZE //total size of a blk
#define HEAP_EXTEND_SIZE ((BLK_SIZE)*1024) //the total heap size

static void *base_heap = NULL; //base of the heap, starting point
static void *end_heap = NULL;
static block_header *freeblk = NULL;

void *mymalloc(size_t size) {
    size_t remainder_heap = (HEAP_EXTEND_SIZE) - (BLK_SIZE);

    // first time init the heap and allocate the first block
    if (!base_heap) {
        base_heap = sbrk(0);
        end_heap = sbrk(HEAP_EXTEND_SIZE);
        if (base_heap == (void*)-1 || end_heap == (void*)-1)
            return NULL;

        block_header *blk = (block_header*)base_heap;
        blk->size = BLK_SIZE;
        blk->zero = 2;
        blk->alloc = 1;

        freeblk = ((void*)(base_heap)) + BLK_SIZE;
        freeblk->size = remainder_heap;
        freeblk->zero = 2;
        freeblk->alloc = 0;

        return ((void*)blk) + HEADER_BLK_SIZE;
    } else
    if (size >= HEAP_EXTEND_SIZE) {
        return NULL;
    } else {
    //second time and the others
        block_header *ptr = (block_header*)base_heap;
        size_t i;
        i = 0;
        while (i < (HEAP_EXTEND_SIZE)) { //travel the heap
            if ((ptr->alloc) ==1 ) { //if it's allocate we go to the nxt block
                ptr = ((void*)ptr) + ((size_t)(ptr->size));
                i += ((size_t)(ptr->size));
            } else
            if ((ptr->alloc) == 0 && ptr->size > BLK_SIZE) { /*if it's free and
                                                              big enough */
                ptr->size = BLK_SIZE;
                ptr->zero = 2;
                ptr->alloc = 1;
                return ((void*)ptr) + (HEADER_BLK_SIZE);
            } else { //not big enough so we go to the next block
                ptr = ((void*)ptr) + ((size_t)(ptr->size));
                i += ((size_t)(ptr->size));
            }
        }
        return NULL; //if it does not wok
    }
}

//for testing my code
void main() {
    int *i =(int*)mymalloc(12);
    printf("pointeur i : %p\n", i);

    int *ii = (int*)mymalloc(16);
    printf("pointeur ii : %p\n", ii);

    int *iii = (int*)mymalloc(20);
    printf("pointeur iii : %p\n", iii);

    int *iiii = (int*)mymalloc(24);
    printf("pointeur iiii : %p\n", iiii);
}
/*作者:辛格*/
typedef结构块头{
无符号整数大小:29,
零:2,,
alloc:1;
}块头;
//宏
#定义标头\u BLK\u sizeof(块\u标头)//4字节标头
#定义对齐的负载大小(((((大小)-1)>>2)零=2;
blk->alloc=1;
freeblk=((void*)(base_heap))+BLK_SIZE;
freeblk->size=剩余值\u堆;
freeblk->zero=2;
freeblk->alloc=0;
返回((空*)黑色)+标题黑色大小;
}否则
如果(大小>=堆大小){
返回NULL;
}否则{
//第二次和其他
块头*ptr=(块头*)基本堆;
尺寸i;
i=0;
而(i<(HEAP\u EXTEND\u SIZE)){//遍历堆
如果((ptr->alloc)==1){//如果是分配,则转到nxt块
ptr=((void*)ptr)+((size_t)(ptr->size));
i+=((尺寸(ptr->尺寸));
}否则
如果((ptr->alloc)==0&&ptr->size>BLK_size){/*如果它是免费的并且
足够大*/
ptr->size=BLK_size;
ptr->0=2;
ptr->alloc=1;
返回((void*)ptr)+(表头黑色大小);
}否则{//不够大,所以我们去下一个街区
ptr=((void*)ptr)+((size_t)(ptr->size));
i+=((尺寸(ptr->尺寸));
}
}
返回NULL;//如果不起作用
}
}
//用于测试我的代码
void main(){
int*i=(int*)mymalloc(12);
printf(“指针i:%p\n”,i);
int*ii=(int*)mymalloc(16);
printf(“指针ii:%p\n”,ii);
int*iii=(int*)mymalloc(20);
printf(“指针iii:%p\n”,iii);
int*iiii=(int*)mymalloc(24);
printf(“指针iiii:%p\n”,iiii);
}

如果我更改此部分:

  else{
      block_header* ptr = (block_header*) base_heap;
      size_t i;
      i = 0;
      while(i<(HEAP_EXTEND_SIZE)){ //travel the heap
        if((ptr->alloc)==1){ //if it's allocate we go to the nxt block
          ptr = ((void*)ptr) + ((size_t)(ptr->size));
          i += ((size_t)(ptr->size));
        }
        else if((ptr->alloc)==0 && ptr->size > BLK_SIZE){ /*if it's free and
                                                            big enough */
            ptr->size = BLK_SIZE;
            ptr->zero = 2;
            ptr->alloc = 1;
            return ((void*)ptr) + (HEADER_BLK_SIZE);
        }
        else{ //not big enough so we go to the next block
          ptr = ((void*)ptr) + ((size_t)(ptr->size));
          i += ((size_t)(ptr->size));
        }
      }
      return NULL; //if it does not wok
    }
else{
块头*ptr=(块头*)基本堆;
尺寸i;
i=0;
而(ialloc)=1{//如果是分配,则转到nxt块
ptr=((void*)ptr)+((size_t)(ptr->size));
i+=((尺寸(ptr->尺寸));
}
else如果((ptr->alloc)==0&&ptr->size>BLK_size){/*如果它是免费的并且
足够大*/
ptr->size=BLK_size;
ptr->0=2;
ptr->alloc=1;
返回((void*)ptr)+(表头黑色大小);
}
否则{//不够大,所以我们去下一个街区
ptr=((void*)ptr)+((size_t)(ptr->size));
i+=((尺寸(ptr->尺寸));
}
}
返回NULL;//如果不起作用
}
在这一部分(它不再知道空闲块是否足够大),我认为它“有效”

else{
      block_header* ptr = (block_header*) base_heap;
      size_t i;
      i = 0;
      while(i<(HEAP_EXTEND_SIZE)){
        if((ptr->alloc)==1){
          ptr = ((void*)ptr) + ((size_t)(ptr->size));
          i += ((size_t)(ptr->size));
        }
        else{
          ptr->size = BLK_SIZE;
          ptr->zero = 2;
          ptr->alloc = 1;
          return ((void*)ptr) + (HEADER_BLK_SIZE);
        }
      }
      return NULL;
    }
    return NULL;
  }
else{
块头*ptr=(块头*)基本堆;
尺寸i;
i=0;
而(ialloc)==1){
ptr=((void*)ptr)+((size_t)(ptr->size));
i+=((尺寸(ptr->尺寸));
}
否则{
ptr->size=BLK_size;
ptr->0=2;
ptr->alloc=1;
返回((void*)ptr)+(表头黑色大小);
}
}
返回NULL;
}
返回NULL;
}

如果我更改此部分:

  else{
      block_header* ptr = (block_header*) base_heap;
      size_t i;
      i = 0;
      while(i<(HEAP_EXTEND_SIZE)){ //travel the heap
        if((ptr->alloc)==1){ //if it's allocate we go to the nxt block
          ptr = ((void*)ptr) + ((size_t)(ptr->size));
          i += ((size_t)(ptr->size));
        }
        else if((ptr->alloc)==0 && ptr->size > BLK_SIZE){ /*if it's free and
                                                            big enough */
            ptr->size = BLK_SIZE;
            ptr->zero = 2;
            ptr->alloc = 1;
            return ((void*)ptr) + (HEADER_BLK_SIZE);
        }
        else{ //not big enough so we go to the next block
          ptr = ((void*)ptr) + ((size_t)(ptr->size));
          i += ((size_t)(ptr->size));
        }
      }
      return NULL; //if it does not wok
    }
else{
块头*ptr=(块头*)基本堆;
尺寸i;
i=0;
而(ialloc)=1{//如果是分配,则转到nxt块
ptr=((void*)ptr)+((size_t)(ptr->size));
i+=((尺寸(ptr->尺寸));
}
else如果((ptr->alloc)==0&&ptr->size>BLK_size){/*如果它是免费的并且
足够大*/
ptr->size=BLK_size;
ptr->0=2;
ptr->alloc=1;
返回((void*)ptr)+(表头黑色大小);
}
否则{//不够大,所以我们去下一个街区
ptr=((void*)ptr)+((size_t)(ptr->size));
i+=((尺寸(ptr->尺寸));
}
}
返回NULL//如果它不起作用
}
在这一部分(它不再知道空闲块是否足够大),我认为它“有效”

else{
      block_header* ptr = (block_header*) base_heap;
      size_t i;
      i = 0;
      while(i<(HEAP_EXTEND_SIZE)){
        if((ptr->alloc)==1){
          ptr = ((void*)ptr) + ((size_t)(ptr->size));
          i += ((size_t)(ptr->size));
        }
        else{
          ptr->size = BLK_SIZE;
          ptr->zero = 2;
          ptr->alloc = 1;
          return ((void*)ptr) + (HEADER_BLK_SIZE);
        }
      }
      return NULL;
    }
    return NULL;
  }
else{
块头*ptr=(块头*)基本堆;
尺寸i;
i=0;
而(ialloc)==1){
ptr=((void*)ptr)+((size_t)(ptr->size));
i+=((尺寸(ptr->尺寸));
}
否则{
ptr->size=BLK_size;
ptr->0=2;
ptr->alloc=1;
返回((void*)ptr)+(表头黑色大小);
}
}
返回NULL;
}
返回NULL;
}

您的代码中存在一个主要问题:

#define ALIGNED_PAYLOAD_SIZE (((((size)-1)>>2)<<2)+4) //to align the payload
#define BLK_SIZE HEADER_BLK_SIZE + ALIGNED_PAYLOAD_SIZE //total size of a blk
#define HEAP_EXTEND_SIZE ((BLK_SIZE)*1024) //the total heap size
实际上扩展到

if(size >= ((HEADER_BLK_SIZE + (((((size)-1)>>2)<<2)+4))*1024))

如果(size>=((HEADER_BLK_size+(((((((((((size))1)>>2)您的代码中存在一个主要问题:

#define ALIGNED_PAYLOAD_SIZE (((((size)-1)>>2)<<2)+4) //to align the payload
#define BLK_SIZE HEADER_BLK_SIZE + ALIGNED_PAYLOAD_SIZE //total size of a blk
#define HEAP_EXTEND_SIZE ((BLK_SIZE)*1024) //the total heap size
实际上扩展到

if(size >= ((HEADER_BLK_SIZE + (((((size)-1)>>2)<<2)+4))*1024))
if(size>=((页眉黑色大小+((((((((大小)-1))大于2)
在我看来,根本原因是你在分配一个挡块后忘记处理自由挡块点。你需要处理自由挡块点的原因是你需要自由挡块来做出判断。
以下是我的修改:

经过测试,我发现它有效。
在此处输入代码
[zzhen201@~]$。/测试 指针一:0x2097004 指针ii:0x2097024 指针iii:0x209703c 三级指针:0x2097058

但是,我没有添加更多的测试来测试是否存在任何其他bug。 所以也许你需要做更多的工作来测试这个

在我看来,根本原因是你