C语言代码编译通过运行触发segmentation fault段错误的原因是什么
段错误触发原因
- 未处理
strstr查找失败的情况:如果某一行不存在Date:子串,strstr会返回NULL,此时执行i=ptr-line相当于对空指针做地址运算,得到的i是非法值,后续访问line[i]就会直接触发内存访问越界,也就是你遇到的段错误。 - 索引
j未在每行处理前重置:j定义在循环外部,会持续累加,处理多行后j的大小会超过substr数组的5000长度限制,导致substr[j]写入越界,破坏栈内存触发段错误。 substr未手动补充字符串结束符:C语言字符串必须以\0结尾,你提取内容后没有给substr加结束标记,后续printf("%s")读取时会一直向后访问内存直到遇到随机的\0,很容易触发越界访问。- 偏移计算错误存在越界风险:
Date:的长度仅为5个字符,你使用line[i+9]取值,当i接近行尾时i+9会超出line数组的合法访问范围,也会触发非法内存访问。
修复后参考代码
#include <stdio.h> #include <string.h> int main() { char const* const fName = "database-large.txt"; FILE* fp = fopen(fName, "r"); char substr[5000]; // 打开失败直接返回 if(!fp){ printf("\n Error in open : %s ", fName); return -1; } char line[5000]; const char* prefix = "Date:"; const int prefix_len = strlen(prefix); // 逐行读取 while (fgets(line, sizeof(line), fp)) { char* ptr = strstr(line, prefix); // 没有Date:字段直接跳过当前行 if (ptr == NULL) { continue; } long j = 0; // 移动指针到Date:之后的位置 ptr += prefix_len; while(*ptr != '\n' && *ptr != '\0') { substr[j] = *ptr; ptr++; j++; // 防止substr数组越界 if (j >= sizeof(substr) - 1) { break; } } // 补充字符串结束符 substr[j] = '\0'; printf("%s\n", substr); } fclose(fp); return 0; }
内容的提问来源于stack exchange,提问作者PlayboyyQ
相关产品推荐
相关产品推荐

