C语言实现tail工具时partial write()触发内存溢出问题求助
C语言tail工具partial write异常与内存溢出问题修复
你代码中存在4个核心逻辑错误,直接导致partial write工作异常和内存溢出:
- write循环参数错误,固定写入长度触发越界
当前write循环固定每次写入read_size(100字节),当剩余待写入内容不足100字节时,会读取buff尾部之外的非法内存,既会输出垃圾内容,也会触发内存访问溢出。
同时你没有判断待写入的总长度上限,循环没有终止边界,只要write返回大于0就会一直往后读越界内存,必然出现溢出。 - 扩容判断时机错误,read前未检查剩余空间
当前你是先执行read、更新偏移量之后再判断是否需要扩容,当剩余空间不足以容纳本次read的最大长度时,read操作已经把数据写到了buff分配的内存之外,直接造成堆内存溢出。 - 空字符赋值位置逻辑错误
buff[offset] = '\0'写在if分支外部,当进入else分支时offset仍为0,会直接把buff首地址改写为结束符,导致后续输出为空;如果if分支中write出错返回-1,offset偏移量异常,也会出现越界写空字符的问题。 - read返回值判断冗余,类型定义错误
while循环的判断条件已经过滤了read()<=0的情况,循环内部再判断res == -1属于无效逻辑;同时read、write的返回值是有符号的ssize_t类型,你定义为无符号size_t会导致返回-1时数值溢出,逻辑判断失效。
修复后的核心逻辑代码
int fd = open(path, O_RDONLY); if(fd == -1) { /* 错误处理逻辑 */ } const size_t read_size = 100; size_t size = read_size; size_t offset = 0; ssize_t res = 0; char *buff = malloc(size + 1); if (!buff) { /* 内存分配错误处理逻辑 */ } int lines = 0; while(1) { // 先检查扩容,确保剩余空间足够容纳一次read的最大长度 if (offset + read_size > size) { size *= 2; char *new_buff = realloc(buff, size + 1); if (!new_buff) { /* 扩容错误处理,释放原有buff后退出 */ } buff = new_buff; } res = read(fd, buff + offset, read_size); if (res == -1) { /* 读错误处理逻辑 */ } if (res == 0) { break; } // 读到文件结束 offset += res; buff[offset] = '\0'; } // 统计行数 for(size_t i = 0; i < offset; i++) { if(buff[i] == '\n') { lines++; } } if(lines < 10) { size_t write_offset = 0; size_t total_write = offset; // 明确待写入的总长度 while(write_offset < total_write) { // 每次写入剩余未写的长度,适配partial write场景 res = write(STDOUT_FILENO, buff + write_offset, total_write - write_offset); if (res == -1) { /* 写错误处理逻辑 */ } write_offset += res; } } else { // 原有查找倒数10行起始位置的逻辑 } free(buff); close(fd);
额外优化提示
统计行数时直接用已读取的总偏移量offset做边界判断,不需要依赖字符串结束符,避免buff中间出现'\0'导致行数统计错误。
内容的提问来源于stack exchange,提问作者Inakis Girou
相关产品推荐
相关产品推荐

