为啥这个 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 函数会给我一个分段错误?的主要内容,如果未能解决你的问题,请参考以下文章
为啥定义复制构造函数会给我错误:不能将'obj&'类型的非常量左值引用绑定到'obj'类型的右值?
当我在 ngOnInit() 中使用 router.getCurrentNavigation() 时,它会给我类型错误,但是当我在构造函数中使用它时,它工作正常,为啥?