C语言实现可控缓冲区读文件输出时遇无限循环无输出问题求助
问题修复方案
原代码问题点
- 内存越界:你分配的buf大小为
size,但代码尝试将整个文件(大小为taille)全部写入buf,当taille > size时直接触发越界访问,引发未定义行为。 - 无限循环诱因1:未判断
read的返回值,若read调用出错返回-1,n会反向减小,永远无法达到taille,陷入死循环。 - 无限循环诱因2:
read的第三个参数写为taille -n -1,同时没有限制单次读取长度不超过缓冲区剩余可用空间,既可能读超缓冲区,也可能在剩余要读的长度计算错误时卡住。 - 逻辑不符合需求:需求要求缓冲区大小可控,不需要一次性把整个文件读入内存,原代码的实现逻辑本质是要把整个文件装进缓冲区,本身就不符合缓冲区大小独立于文件大小的要求。
- 缺少错误处理:
malloc、open、read、write调用都没有做失败判断,出错后无法感知也无法正常退出。
修正后实现
修正思路为循环读取,每次最多读buf_size字节,读多少就输出多少,不需要缓存整个文件,缓冲区大小固定为传入的参数,完全符合需求:
#include <unistd.h> #include <fcntl.h> #include <stdlib.h> void cat(int buf_size, const char *path) { // 缓冲区申请和错误判断 char *buf = malloc(buf_size); if (buf == NULL) { return; } // 文件打开错误判断 int fd = open(path, O_RDONLY); if (fd < 0) { free(buf); return; } ssize_t read_len; // 循环读取,每次最多读buf_size字节 while ((read_len = read(fd, buf, buf_size)) > 0) { // 保证读到的内容全部输出,处理write可能的部分写入情况 ssize_t written = 0; while (written < read_len) { ssize_t w_ret = write(STDOUT_FILENO, buf + written, read_len - written); if (w_ret < 0) { break; } written += w_ret; } } // 资源释放 free(buf); close(fd); }
内容的提问来源于stack exchange,提问作者Bendaoud Simou
相关产品推荐
相关产品推荐

