当fgets读取大小小于缓冲区大小时是否存在危险?代码安全性问询
这段C代码的潜在风险分析
Hey,咱们来拆解这段代码里的几个容易被忽略的风险点:
未检查
fgets的返回值是最大的隐患
当fgets读取失败时(比如文件是空的、读的时候出了I/O错误,或者已经读到文件末尾),它会返回NULL。这时候line数组里的内容是完全未初始化的垃圾数据,如果后续代码用到line(比如打印、做字符串处理),就会触发未定义行为——可能输出乱码,甚至让程序直接崩溃。举个修复的例子:
if (NULL != file) { if (fgets(line, 40, file) != NULL) { // 这里安全处理读取到的内容 } else { // 处理读取失败的情况,比如打印错误日志 } fclose(file); }对
fgets的参数理解有偏差,可能导致逻辑错误
你提到“最多读取40长度的字符串”,这里得纠正一下:fgets的第二个参数是包含终止符\0在内的最大字节数,所以它实际最多会读39个字符,然后自动补\0。如果文件里的某一行超过39个字符,fgets会直接截断这行,剩下的字符留在文件流里。这段代码读完就关文件了,不会直接出问题,但如果你的业务逻辑需要完整读取一行(比如配置项、用户输入),这种截断就会导致数据丢失,进而引发逻辑bug。
(次要)野指针隐患
调用fclose(file)之后,file指针并没有被置为NULL,它会变成一个野指针(指向已经释放的内存地址)。虽然这段代码里没有后续操作,但如果之后不小心复用这个指针(比如误判file是否有效),就会触发未定义行为。这是个不好的编码习惯,建议关闭文件后把指针置空:fclose(file); file = NULL;
值得一提的是,这段代码不会导致缓冲区溢出——因为line的大小是80字节,而fgets最多只写40字节(39个字符+1个终止符),所以内存安全这块倒是没问题。但上面的几个点都是需要重视的隐性风险哦。
内容的提问来源于stack exchange,提问作者Thai
相关产品推荐
相关产品推荐

