为啥这个 fgets 函数会给我一个分段错误?

Posted

技术标签:

【中文标题】为啥这个 fgets 函数会给我一个分段错误?【英文标题】: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;

【问题讨论】:

【参考方案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 谢谢。在短语中包含空指针。

以上是关于为啥这个 fgets 函数会给我一个分段错误?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 pHp 会给我这个错误? [复制]

请解释为啥这个 C 代码给我一个分段错误?

为啥 heroku 会给我这个“不兼容的类型”错误?

为啥这个表创建脚本会给我错误?

为啥定义复制构造函数会给我错误:不能将'obj&'类型的非常量左值引用绑定到'obj'类型的右值?

当我在 ngOnInit() 中使用 router.getCurrentNavigation() 时,它会给我类型错误,但是当我在构造函数中使用它时,它工作正常,为啥?