【问题标题】:I'am getting a Segmentation fault while using fgetc(). How can I fix it?使用 fgetc() 时出现分段错误。我该如何解决?
【发布时间】:2016-06-19 07:40:04
【问题描述】:

我想从文件流中读取 z 个字节。然后我想将 char 数组中的值返回。如果您能给我一个解释,我将不胜感激。从现在开始,这就是我的代码:

char * getData(FILE * fp, long * x)
{
  int z = 0;
  char * data = malloc(sizeof(char) * BUFFLENGTH);
  strcpy(data,"");

  while(z < BUFFLENGTH-2)
  {
    if(feof(fp) == 0)
    {
      data[z] = fgetc(fp);
      z++;
      x++;
    }
    else
    {
       strcat(data,"\0");
       return data;
    }
  }    
}

我知道触发了分段错误抛出了这一行:

data[z] = fgetc(fp);

但我不知道为什么。

【问题讨论】:

  • 确保索引在范围内并且fp 不是NULL
  • strcat(data,"\0"); 旨在追加零字节,但会导致 未定义的行为,因为不是指向以空字符结尾的字符串的指针可能会作为第一个参数传递。
  • 真的知道触发分段错误的行,使用调试器或其他什么?你没有发布你的想象力,是吗?
  • @MikeCAT ...但仍取决于data[]的内容...顺便说一句:count 是循环不变的,*x 从未被引用。

标签: c char segmentation-fault fgetc


【解决方案1】:
  • 您应该检查分配是否成功。
  • 您应该在调用fgetc() 而不是使用feof() 之后检查读取是否成功
  • strcat() 的这种用法将调用 未定义的行为,如果从文件中读取一个或多个字节并且没有读取其值为 0 的字节,因为指针指向的不是以空值结尾的东西string 将被传递给strcat(),它将访问通过malloc() 分配的区域,而不是初始化。取而代之的是,您应该通过添加 '\0' 来终止字符串。
  • 即使读取的长度超过限制,您也应该显式返回某些内容,否则如果调用者使用返回值,您将调用 未定义的行为

应用了这些建议的代码:

char * getData(FILE * fp, long * x)
{
  int z = 0;
  char * data = malloc(sizeof(char) * BUFFLENGTH);
  if(data == NULL) return NULL;
  /* strcpy() isn't needed because it will be overwritten */

  while(z < BUFFLENGTH-2)
  {
    int input = fgetc(fp);
    if(input != EOF)
    {
      data[z] = input;
      z++;
      x++;
    }
    else
    {
       data[z] = '\0';
       return data;
    }
  }
  free(data);
  return NULL;
}

【讨论】:

  • 我尝试通过以下方式访问它:char * new = getData(fp, &byteatm); printf("%s", new);但它总是说(空)。如果你在while循环之后释放(数据)它不会在内存中销毁吗?
  • free() 将破坏内存中的内容(有效性)。使文件大小低于限制或更改过大文件的处理。
  • 这只是一个 1042 字节的文件。这么小的文件怎么会这么大?
  • 取决于BUFFLENGTH的值。例如,如果其值为80,则任何 78 字节或更大的文件都太大。
  • 但是如果到达 EOF,它会返回数据并离开函数,或者?
猜你喜欢
  • 1970-01-01
  • 2014-07-28
  • 2019-06-28
  • 2019-08-02
  • 2020-08-18
  • 1970-01-01
  • 2021-09-15
  • 1970-01-01
  • 2021-11-14
相关资源
最近更新 更多