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

我标记了给我带来问题的区域......当我将它留在我的函数中时,它不会输出正确的数据,但不会出现段错误。有人能告诉我这个错误代码对那条线意味着什么吗?

4

3 回答 3

1

这里有几个错误:

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

肯定没有空间容纳两个 uint8_tj

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

你有一个+1 ,但你在分配时没有为那个字节分配空间img->data

如需其他帮助,请在valgrind中运行您的程序,这在跟踪此类错误时非常有帮助。

于 2013-10-12T01:28:32.973 回答
1

错误消息意味着您正在使用free已释放的指针。问题是这种错误有点难以找到,因为 usingfree只告诉 SO 内存在需要时可以使用,但它并不一定会阻止您访问该内存。例如:

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

不会产生错误,如果a再次尝试释放,则会得到双重释放的错误。

从手册页来看,free如果您尝试双重释放某些东西,则会出现未定义的行为,但如果您尝试free(NULL)将不会出现错误。因此,不要使用一堆if's来控制您必须释放哪些指针,只需使用:

free(ptr);
ptr = NULL;

这样,如果您再次尝试释放,您将不会出错。

于 2013-10-12T01:32:50.620 回答
1

nos cenouro 所指出的都是有效的事情。而不是一块一块地挑选所有的记忆错误。试试这个叫做Valgrind的东西。它运行您的整个程序并检查各处的内存错误。这真的是一个救生员。

于 2013-10-12T01:37:40.807 回答