为什么调用fgets函数时会出现segmentation fault(段错误)?
问题根因分析
你贴出的问题代码如下:
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执行阶段触发段错误的直接原因
传入的FILE* fp为非法指针:
- 可能是fp为NULL,比如文件打开失败未做判空就直接传入
- 也可能是fp指向的文件已经被提前调用
fclose关闭 - 或者fp本身是未初始化的野指针
fgets操作非法文件流会直接触发内存访问越界,抛出段错误。
2. 代码中其他会触发段错误/未定义行为的问题
- 非法释放栈内存:
temp = maxstr让temp指向了栈上分配的数组maxstr,而free只能释放堆上由malloc/calloc/realloc动态申请的内存,释放栈内存属于严重的未定义行为,哪怕fgets执行成功,运行到free(temp)这行也一定会触发内存崩溃。 - 内存申请长度不足:
calloc(strlen(maxstr), sizeof(char))只申请了等于字符串有效长度的内存,没有预留1字节存储字符串结束符\0,后续如果拷贝字符串到exp会发生缓冲区溢出,破坏内存结构。 - 逻辑功能错误:代码申请
exp后没有做任何内容拷贝操作,直接打印和返回的exp是全0的空内存,完全无法实现读取文件内容返回的预期效果。
修正后的参考代码
#include <stdio.h> #include <stdlib.h> #include <string.h> const char* display_exp(FILE* fp){ // 先对入参做判空,避免非法指针访问 if (fp == NULL) { return NULL; } char maxstr[50]; char* exp; if (fgets(maxstr, sizeof(maxstr), fp) == NULL) { // fgets读取失败(比如到文件末尾)做异常处理 return NULL; } // 申请长度+1预留结束符位置 exp = (char*)calloc(strlen(maxstr) + 1, sizeof(char)); if (exp == NULL) { return NULL; } // 把读取到的内容拷贝到动态申请的内存中 strcpy(exp, maxstr); printf("%s", exp); return exp; }
注意:调用该函数的地方需要在使用完返回的exp指针后,手动调用free释放内存,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Mohamed Elkasimi
相关产品推荐
相关产品推荐

