2014-12-22 64 views
0

我得到了下面的代碼和平segmentation fault (core dumped)段錯誤(我執行malloc()free()realloc()):一個奇怪的不明原因

void free(void* ptr) 
{ 
    void* curr = head; 
    void* before = NULL; 
    int isLegal = 0; 
    /*Line X*/printf("curr is %p and ptr is %p\n", curr, ptr); 
    if(curr == ptr) 
    { 
     printf("aaa"); 
    } 
    else 
    { 
     printf("bbb"); 
    } 
    /*Some more code that actually frees the pointer and not relevant here*/ 
} 

現在,你會認爲它會打印aaabbb,它只是在執行第X行中的printf()後立即宣佈分段錯誤。如果我鍵入「printf(」a「)」而不是當前的printf(),它將根本不打印'a'。這真的很奇怪。 它打印:

curr is 0x86be000 and ptr is 0x86be000 

,但它只是退出,之後扔分割故障。 變量head是該文件中的一個靜態變量。我真的很想知道問題在哪裏,這真的很奇怪。以下是頭文件中的聲明:

void free(void* ptr); 

就這麼簡單,你看到這裏有什麼問題嗎? 完整的代碼是可用的here但我懷疑它是相關的,程序應該至少打印'aaa'或'bbb',但它不這樣做。 有什麼想法?我真的很絕望。帶有警告遵守,但

+4

代碼既然你不不打印換行符或使用'fflush',您的printf輸出不會被刷新。如果您正在使用它們進行調試,則應在每個打印語句中使用換行符。 – JS1

+0

@ JS1我不明白,你基本上說我應該只是添加'\ n'或使用'fflush(stdout)'?不與任何工作。 – Jack

+0

因此,在更改'aaa'和'bbb'來添加換行符後,您在輸出中看不到任何內容,但仍然可以看到以前的printf輸出?我不是說它會修復你的segv,只是你應該看到'aaa'或'bbb'。 segv可能在稍後發生。 – JS1

回答

0

下面的代碼沒有執行完全

#include <unistd.h> 
typedef struct metadata_block* p_block; 

typedef struct metadata_block 
{ 
     size_t size; 
     p_block next; 
     int free; 
}metadata_block; 

void* malloc(size_t size); 
void free(void* ptr); 
void* realloc(void* ptr, size_t size); 

//THE MAIN CODE IS AT THE BOTTOM// 
#include <stdio.h> 

static p_block head = NULL; 

void* malloc(size_t size) 
{ 
     void* ptr; 
     int isOk = 1; 
     int temp = 0; 
     p_block curr = head; 
     if(size <= 0) 
     { 
       return NULL; 
     } 
     if(curr) 
     { 
       while(curr->next && isOk) 
       { 
         if(curr->free && size <= curr->size) 
         { 
           isOk = 0; 
         } 

         if(isOk) 
         { 
           curr = curr->next; 
         } 
       } 

       if(isOk) //what will happen if there isn't one free and big enough 
       { 
         ptr = sbrk(size + sizeof(metadata_block)); 
         if((int)ptr <= 0) 
           return NULL; 
         ((p_block)(ptr))->size = size; 
         ((p_block)(ptr))->next = NULL; //next run it's the real next. 
         ((p_block)(ptr))->free = 0; 

         return (ptr + sizeof(metadata_block)); 
       } 
       else 
       { 
         if(curr->next) 
         { 
           ptr = curr; 
           if(curr->size == size || size > (curr->size - sizeof(metadata_block) - 1)) //not enough room for another block of memory 
           { 
             ((p_block)(ptr))->free = 0; 
             return (ptr + sizeof(metadata_block)); 
           } 

           temp = curr->size; 
           ((p_block)(ptr))->size = size; 
           ((p_block)(ptr))->free = 0; 
           ((p_block)(ptr + sizeof(metadata_block) + size))->next = curr->next; 
           ((p_block)(ptr))->next = ptr + sizeof(metadata_block) + size; 
           ((p_block)(ptr + sizeof(metadata_block) + size))->size = temp - size; 
           ((p_block)(ptr + sizeof(metadata_block) + size))->free = 1; 

           return (ptr + sizeof(metadata_block)); 
         } 
         else 
         { 
           ptr = curr; 
           if((int)sbrk(size - curr->size) > 0) 
           { 
             ((p_block)(ptr))->size = size; 
             ((p_block)(ptr))->next = NULL; //next run it's the real next. 
             ((p_block)(ptr))->free = 0; 

             return (ptr + sizeof(metadata_block)); 
           } 
           return NULL; 
         } 
       } 
     } 
     else 
     { 
       ptr = sbrk(size + sizeof(metadata_block)); 
       if((int)ptr <= 0) 
         return NULL; 
       head = ptr; 
       ((p_block)(ptr))->size = size; 
       ((p_block)(ptr))->next = NULL; 
       ((p_block)(ptr))->free = 0; 
     } 


     return ptr; 
} 

void free(void* ptr) 
{ 
     void* curr = head; 
     void* before = NULL; 
     int isLegal = 0; 
     printf("curr is %p and ptr is %p\n", curr, ptr); 
     if(curr == ptr) 
     { 
       printf("aaa\n"); 
     } 
     else 
     { 
       printf("bbb\n"); 
     } 
     if(curr && ptr) 
     { 
       while(curr && !isLegal) 
       { 
         if(((p_block)(ptr)) == ((p_block)(curr))->next) 
         { 
           before = curr; 
           isLegal = 1; 
           curr = ((p_block)(curr))->next; 
         } 
         else 
         { 
           curr = ((p_block)(curr))->next; 
         } 
       } 

       if(isLegal) 
       { 
         curr = curr - sizeof(metadata_block); 

         if(((p_block)(curr))->next) 
         { 
           ((p_block)(curr))->free = 1; 
         } 
         else 
         { 
           sbrk(0-(((p_block)(curr))->size + sizeof(metadata_block))); 
           ((p_block)(before))->next = NULL; 
         } 
       } 
     } 
} 

void* realloc(void* ptr, size_t size) 
{ 
     void* ptr2 = malloc(size); 
     int i; 
     for(i = 0 ; i < size ; i++) 
     { 
       *((char*)(ptr2 + i)) = *((char*)(ptr + i)); 
     } 

     free(ptr); 

     return ptr2; 
} 


int main() 
{ 
     printf("I'm in.\n"); 
     char * str = malloc(10); 
     printf("After Malloc()\n"); 
     void * ptr = (void *) str; 
     void * ptr2; 
     if(!str) 
     { 
       printf("Fail.\n"); 
     } 
     strcpy(str,"TEST!\0"); 
     printf("About to free\n"); 
     free(str); 
     printf("free: OK!\n"); 
} 

輸出:

I'm in.             
After Malloc()            
About to free            
curr is 0x1049000 and ptr is 0x1049000      
aaafree: OK! 

注意 - 您的mm.h的Instaed包括我包含在同一個文件

+0

的確,在添加'\ n'之後它就起作用了。謝謝,我不知道這是在Unix的關鍵。 – Jack

+0

@kcdod不錯的努力。但是,如果您可以說明OP代碼中的問題以及您爲解決問題所做的更改,這對未來的訪問者將會非常有幫助。謝謝。 :-) –