2016-03-14 56 views
0

我試圖在C中實現我自己的malloc()函數,但是我正面臨着這個問題。前兩個分配的地址是正確的,但在此之後,它不顯示其他地址。我的意思是,它陷入了無限循環。但是,如果我刪除條件&& ptr->size > BLK_SIZE,它似乎工作。所以,問題是,爲什麼這種情況會破壞代碼?這怎麼可能通過除了解除條件以外的其他方式解決?定製malloc中的無限循環()

這裏是我的代碼...

/* 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); 
} 

回答

0

如果我改變這個部分:這部分

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{ 
     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; 
    } 
1

有一個在你的代碼的一個主要問題:

#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 

所有這些宏指的是一些當前的size變量。 sizemymalloc的參數的名稱,使所有這些標識符不是常量。這可能不是你的意圖......

例如,無辜樣子測試:

if(size >= HEAP_EXTEND_SIZE) 

實際上擴展到

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

除非出現無符號運算溢出,並評估對哪個是假的巧合。

您必須先清理代碼纔能有效地進行調試。

1

在我看來,根本原因是你忘記處理空閒塊點後,你分配一個塊。你需要處理freeblock的原因是你需要freeblock做一些判斷。 下面是我的修改:

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; 
     freeblk = ((void *)ptr) + (size_t)(ptr->size); 
     freeblk->size = freeblk->size - ptr->size; 
     freeblk->zero = 2; 
     freeblk->alloc = 0; 
     return ((void*)ptr) + (size_t)(ptr->size); 
    } 

試驗後,我發現它的工作原理。 enter code here [zzhen201 @〜] $ ./test pointeur我:0x2097004 pointeur二:0x2097024 pointeur III:0x209703c pointeur IIII:0x2097058

不過,我並沒有增加更多的測試,以測試是否有任何其他錯誤。 所以,也許你需要做更多的工作來測試這個。