C语言传递结构体字段作为函数参数出现段错误,求原因排查
段错误原因排查与修复建议
1. 未初始化指针导致非法内存写入
main函数中char *dname;是未初始化的野指针,直接调用strcpy(dname, ent->d_name)会向随机内存地址写入数据,这是触发段错误的核心原因之一。
修复方式:为dname分配足够的内存,比如使用栈数组:
char dname[256]; // 足够存储常规文件名的大小 strcpy(dname, ent->d_name);
2. 尝试修改字符串常量导致未定义行为
strcat("/var/log/", dname)中,第一个参数"/var/log/"是字符串常量,存储在只读内存区域。strcat会尝试修改该内存,属于未定义行为,必然触发段错误。
修复方式:分配可写内存拼接完整路径,推荐用snprintf避免缓冲区溢出:
char file_name[512]; snprintf(file_name, sizeof(file_name), "/var/log/%s", ent->d_name);
3. 文件操作未做错误检查
find_string函数中,fopen(filename, "r")可能失败(比如文件无读权限、目标是目录、文件不存在),此时in为NULL,后续调用fscanf(in, ...)和fclose(in)都会操作空指针,引发段错误。
修复方式:添加文件打开的错误检查:
FILE *in = fopen(filename, "r"); if (in == NULL) { fprintf(stderr, "无法打开文件: %s\n", filename); return; }
4. 格式字符串类型不匹配
find_string中的printf语句:
printf("Found occurrence of %s in file %s, line %s\n", s, filename, i);
第三个参数i是int类型,却使用%s格式符,会导致非法内存访问,可能触发段错误。应改为%d:
printf("Found occurrence of %s in file %s, line %d\n", s, filename, i);
5. 输入缓冲区溢出风险
main函数中char s[10];,调用scanf("%10s", s)会读取最多10个字符,加上字符串终止符'\0'会超出数组容量,导致缓冲区溢出,进而引发未定义行为(可能表现为段错误)。
修复方式:限制输入长度为9,留一个位置给终止符:
scanf("%9s", s);
6. 未过滤目录特殊条目
readdir会返回.(当前目录)和..(上级目录)两个特殊条目,拼接路径后尝试打开这些目录,fopen会失败,后续操作空指针也会引发段错误。
修复方式:过滤这两个条目:
while ((ent = readdir(dir)) != NULL) { if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) { continue; } // 后续路径拼接与文件处理逻辑 }
内容的提问来源于stack exchange,提问作者David Power
相关产品推荐
相关产品推荐

