【问题标题】:Why does this fgets function give me a segmentation fault?为什么这个 fgets 函数会给我一个分段错误?
【发布时间】:2022-01-05 01:08:11
【问题描述】:

下面的这个函数在fgets 语句中终止并给出了一个分段错误,我不知道为什么:

const char* display_exp(FILE* fp){

    char maxstr[50];
    char* temp;
    char* exp;
    fgets(maxstr,sizeof(maxstr),fp);

    exp = (char*)calloc(strlen(maxstr),sizeof(char));
    temp=maxstr;

    free(temp);

    printf("%s",exp);

    return exp;
}

【问题讨论】:

    标签: c segmentation-fault dynamic-memory-allocation free fgets


    【解决方案1】:

    您的代码存在多个问题:

    • 您不测试fgets() 是否成功,导致文件末尾出现未定义的行为。

    • 您必须为空终止符分配一个额外的字节。要么使用exp = calloc(strlen(maxstr) + 1, 1); 并检查内存分配失败,要么更好地使用exp = strdup(maxstr);

    • 分配temp = maxstr; 不会复制字符串,您应该使用strcpy(exp, maxstr),或者使用同时执行分配和字符串复制的strdup()

    • free(temp); 尝试释放本地数组,导致未定义的行为。本地数组不需要释放,函数返回时会自动回收其空间,故名自动存储

    • return exp 返回一个指向空字符串的指针,因为您没有将读取到 maxstr 的字符串复制到分配的数组中。

    这是修改后的版本:

    #include <stdio.h>
    #include <string.h>
    
    char *display_exp(FILE *fp) {
        char maxstr[50];
    
        if (fgets(maxstr, sizeof(maxstr), fp)) {
            // return an allocated copy of the line read from the user
            // if the line read has fewer than 49 characters and ends with
            // a newline, this newline is present in the string. You may
            // want to remove it by uncommenting this:
            //maxstr[strcspn(maxstr, "\n")] = '\0';
            return strdup(maxstr);
        } else {
            // fgets encountered a read error or the end of file.
            return NULL;
        }
    }
    

    【讨论】:

      【解决方案2】:

      您不能像您尝试那样为具有自动存储持续时间的数组调用免费函数

      char maxstr[50];
      
      //...
      
      temp=maxstr;
      
      free(temp);
      

      您只能为指向动态分配内存的指针或空指针调用该函数。

      还有这个电话

      printf("%s",exp);
      

      意义不大,因为指针exp指向的动态分配数组包含一个空字符串

      exp = (char*)calloc(strlen(maxstr),sizeof(char));
      

      你的意思好像是这样的

      const char * display_exp(FILE *fp)
      {
          char maxstr[50] = { 0 };
      
          char *exp = NULL;
      
          if ( fgets(maxstr,sizeof(maxstr),fp) != NULL )
          {
              maxstr[ strcspn( maxstr, "\n" ) ] = '\0';
      
              char *exp = malloc( strlen(maxstr) + 1 );
              if ( exp != NULL ) strcpy( exp, maxstr );
          }
      
          return exp;
      }
      

      【讨论】:

      • 赞成,但要挑剔,您也可以使用空指针(不仅仅是指向动态分配的内存的指针)调用free
      • @PaulHankin 谢谢。在短语中包含空指针。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多