C语言调用getline读取文件触发段错误问题排查求助
段错误原因排查
初始代码错误点
getline参数类型不匹配:getline第三个参数要求传入FILE*类型的文件流指针,初始代码传入open返回的int类型文件描述符fd,非法内存访问直接触发段错误。- 内存管理逻辑错误:
getline会自动管理传入的缓冲区内存,当传入的line为NULL、len为0时,会自动分配足够的空间存储行内容,不需要在循环内手动malloc,重复分配既会造成内存泄漏,也会和getline自身的扩容逻辑冲突。 - 功能逻辑冗余:读取到行内容后直接用
sprintf覆盖为固定字符串lala,完全没有用到rules.txt的内容,不符合功能需求。
修正后代码仍段错误的核心原因
fprintf参数顺序完全颠倒:fprintf的第一个参数是目标写入的FILE*指针,第二个参数是格式化字符串,后续为待写入内容。修正后的代码写为fprintf(line,"%s",fout),相当于把fout文件指针当成字符串写入line指向的内存,访问非法地址直接触发段错误。正确写法为fprintf(fout, "%s", line),将读取到的行内容写入目标设备的sysfs节点。- 隐性资源泄漏问题:
getline返回-1(一般为读到文件末尾)时直接return,没有释放line的堆内存,也没有关闭已打开的文件指针,会造成系统资源浪费。
可正常运行的参考实现
#include <stdio.h> #include <stdlib.h> #include <errno.h> int main() { // 打开规则文件 FILE * fp = fopen("./rules.txt", "r"); if (fp == NULL) { perror("open rules.txt failed"); return 1; } // 打开目标设备sysfs节点 FILE* fout = fopen("/sys/class/Rule_Table_Class/Rule_Table_Class_Rule_Table_Device/sysfs_att", "w+"); if (fout == NULL) { perror("open target sysfs node failed"); fclose(fp); return 1; } char * line = NULL; size_t len = 0; ssize_t bytesRead; // 逐行读取直到文件结束 while ((bytesRead = getline(&line, &len, fp)) != -1) { printf("读取到行:%s", line); // 写入目标设备 fprintf(fout, "%s", line); // 刷新缓冲区确保内容立即写入sysfs fflush(fout); } // 释放资源 if (line) { free(line); } fclose(fout); fclose(fp); return 0; }
注意:写入sysfs节点通常需要root权限,若运行报错无权限,使用sudo执行程序即可。
内容的提问来源于stack exchange,提问作者QueryMan
相关产品推荐
相关产品推荐

