运行《Linux系统编程》read示例时报free(): invalid pointer错误如何解决?
问题解决与优化方案
free(): invalid pointer报错的根因非常明确:C标准规定free()必须传入malloc/calloc/realloc等内存分配函数返回的原始指针,你在循环中直接修改了buf指针本身的指向,若不复位到初始地址就调用free必然触发非法指针错误。你目前通过存储偏移复位指针的方案可正常运行,但存在两种更易维护、更低出错概率的优化方案:
方案1:使用临时遍历指针(最推荐)
原始buf指针全程保留初始分配地址不做修改,单独申请一个临时指针负责遍历读写位置,无需手动计算偏移、无需复位,从根源上避免遗漏指针复位的问题。
核心修改逻辑示例:
#include <stdio.h> // 注意malloc.h是非标准头,替换为标准的stdlib.h #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <string.h> int main() { int fd; if( (fd = open("someFile.txt", O_CREAT | O_WRONLY | O_TRUNC, 0664)) < 0) { perror("open for write"); // 出错后直接终止,避免后续逻辑访问非法资源 return 1; } char * text = "This is an example text"; write(fd, text, strlen(text)); close(fd); if( (fd = open("someFile.txt", O_RDONLY)) < 0) { perror("open"); return 1; } char *buf; if( (buf = (char *) calloc(50, sizeof(char))) == NULL ) { perror("calloc"); return 1; } // 单独定义临时遍历指针,不修改原始buf char *curr = buf; int len = 50; ssize_t ret; while (len != 0 && (ret = read (fd, curr, len)) != 0) { if (ret == -1) { if (errno == EINTR) continue; perror ("read"); break; } len -= ret; curr += ret; } if( close(fd) == -1 ) perror("close"); // 原始buf指针始终未改动,直接释放即可 free(buf); return 0; }
方案2:使用数组下标访问
完全不修改指针本身,通过下标偏移计算读取位置,buf指针始终保持初始值:
int offset = 0; while (len != 0 && (ret = read (fd, buf + offset, len)) != 0) { if (ret == -1) { if (errno == EINTR) continue; perror ("read"); break; } len -= ret; offset += ret; } free(buf);
内容的提问来源于stack exchange,提问作者neolith
相关产品推荐
相关产品推荐

