2013-10-12 65 views
0

我有這個功能段錯誤...它給了我,這是錯誤消息...線性規範化段錯誤和內存錯誤

*** glibc detected *** /double free or corruption (fasttop): 0x0000000000603250 *** 
*** glibc detected ***/memory corruption: 0x00007ffff7dd3710 *** 

這是我的所有代碼:

struct Image * loadImage(const char* filename) 
{ 

    //VARIABLES 
struct ImageHeader * hdr2; // on heap, malloc, free 
FILE * fptr = fopen(filename, "r"); 
if (fptr == NULL) 
    { 
    return NULL; 
    } 

int retval; 

hdr2 = malloc(sizeof(struct ImageHeader)); 
if (hdr2 == NULL) 
    { 
    free(hdr2); 
    fclose(fptr); 
    return NULL; 
    } 

retval = fread(hdr2, sizeof(struct ImageHeader), 1, fptr); 

if (retval != 1) 
    { 
    free(hdr2); 
    fclose(fptr); 
    return NULL; 
    // error 
    } 


if (hdr2 -> magic_bits != ECE264_IMAGE_MAGIC_BITS) 
    { 
    free(hdr2); 
    fclose(fptr); 
    return NULL; 
    // error 
    } 

if (hdr2->width == 0||hdr2->height ==0) 
    { 
    free(hdr2); 
    fclose(fptr); 
    return NULL; 
    // error 
    } 



struct Image * img = NULL; 

img = malloc(sizeof(struct Image)); 
if(img == NULL) 
    { 
    fclose(fptr); // free(img); 
    return NULL; 
    //do something 
    } 

img -> width = hdr2 -> width; 
img ->height=hdr2->height;            
img -> comment = malloc(sizeof(char) * (hdr2->comment_len)); 
img -> data = malloc(sizeof(uint8_t) * hdr2->width * hdr2->height); 
retval = fread(img->comment, sizeof(char), hdr2->comment_len, fptr); 

if(img -> comment == NULL) 
    { 
    free(hdr2); 
    free(img->data); 
    free(img->comment); 
    free(img); 
    fclose(fptr); 
    return NULL; 
    //do something, don't forget to free whatever you have allocated 
    } 

//lookg at the img-> comment (should free) 



if (retval != hdr2->comment_len) 
    { 
    free(hdr2); 
    free(img->data); 
    free(img->comment); 
    free(img); 
    fclose(fptr); 
    return NULL; 
    // error 
    } 
/*  
if(img->comment[hdr2->comment_len-1]=='\0')/////////////////////////THIS IS THE PROBLEM AREA 
    { 
    free(hdr2); 
    free(img->data); 
    free(img->comment); 
    free(img);  
    fclose(fptr); 
    return NULL; 
    }*/ 

if(img->data==NULL) 
    { 
    free(hdr2);  
    free(img->comment); 
    free(img);  
    fclose(fptr); 
    return NULL; 
    } 
retval = fread(img->data, sizeof(uint8_t),hdr2->width * hdr2->height, fptr); 

if (retval != (hdr2->width * hdr2->height)) 
    { 

    free(hdr2); 
    free(img->data); 
    free(img->comment); 
    free(img); 
    fclose(fptr); 
    return NULL; 
    } 

    uint8_t j = 0; 
if(fread(&j, sizeof(uint8_t),2,fptr)==2) 
    { 
    free(hdr2); 
    free(img->data); 
    free(img->comment); 
    fclose(fptr); 
    } 



retval = fread(img ->data, sizeof(uint8_t), hdr2->width * hdr2->height +1, fptr); 
    if(retval==hdr2->width*hdr2->height+1) 
    { 
    free(hdr2); 
    free(img); 
    //error 
    fclose(fptr); 
    return NULL; 
    } 


fclose(fptr); 
return (img); 

} 



void freeImage(struct Image * image) 
{ 
    if(image!=NULL) 
    { 
     free(image->data); 
     free(image->comment); 
    } 
    free(image); 
} 


void linearNormalization(struct Image * image) 
{ 
    int index1 = 0; 
    int index2 = 0; 
    //int totaldata = image->height * image->width; 
    int max = 0; 
    int min = 255; 

    // if(image -> data[i] > max) 
    // set max equal to this image 
    for(index1=0; index1<(image->height * image->width); index1++) 
    { 
     if(image->data[index1] > max) 
    { 
     max= image->data[index1]; 
    } 
     if(image->data[index1]<min) 
    { 
     min = image->data[index1]; 
    } 
    }  
    for(index2 = 0; index2<(image->height * image->width);index2++) 
    { 
     image->data[index2] = (image->data[index2]- min) * 255.0/(max - min); 
    } 
} 

我標記了給我提出問題的區域......當我將它放在我的函數中時,不會輸出正確的數據,但不會得到段錯誤。有人能告訴我這個錯誤代碼對於那條線意味着什麼嗎?

+0

你的代碼中有些地方是free'ing空指針。在你檢查過它們是否爲空之前,還有其他地方你可以釋放指針。 –

+0

@CharlieBurns'免費(NULL)'是100%安全。它本質上是一個沒有操作。沒有理由'free(NULL)'會導致錯誤。在這種情況下,他最有可能使指針雙重釋放。 – cyphar

+0

@cyphar,謝謝。我知道(但忘記了)。 「if(hdr2 == NULL) { free(hdr2);」只是看起來馬虎。 –

回答

1

錯誤消息表示您正在使用free指向已經釋放的指針。問題是這種錯誤有點難以找到,因爲使用free只告訴SO如果內存需要時可以自由使用內存,但它不一定會阻止你訪問內存。例如:

int *a = malloc(sizeof(int)); 
*a = 5; 
free(a); 
printf("%d", *a); 

不會產生一個錯誤,如果你嘗試再次釋放a,那麼你將獲得雙倍免費的錯誤。

從手冊頁中,free有未定義的行爲,如果您嘗試雙倍免費的東西,但如果您嘗試free(NULL)將不會有錯誤。因此,而不是使用的if's一堆來控制哪些指針你要自由的,只是使用:

free(ptr); 
ptr = NULL; 

這樣一來,如果你試圖重獲自由,你不會得到和錯誤。

+0

謝謝!這幫助我完成了這個功能! – Liquidmetal

1

這裏有一對夫婦的錯誤:

uint8_t j = 0; 
if(fread(&j, sizeof(uint8_t),2,fptr)==2) 

肯定是存在的j

retval = fread(img ->data, sizeof(uint8_t), hdr2->width * hdr2->height +1, fptr); 

沒有兩個房間uint8_t的你有一個+1那裏,但你有沒有爲字節時分配房間您分配img->data

如需更多幫助,請在valgrind運行程序,它非常棒幫助追蹤這些錯誤。

1

nos cenouro指出的都是有效的東西。儘管如此,我們並沒有將所有的記憶錯誤逐個分開。試試這個叫Valgrind的東西。它運行你的整個程序並檢查各處的內存錯誤。這真是一種生活救星。