代码执行完毕后触发Segmentation fault问题求助
排查你的USACO代码段错误问题
嘿,我一眼就发现了导致段错误的关键问题——你在处理奶牛名字的时候犯了一个常见的内存错误!
问题根源:未初始化的字符指针
你定义了char* cow;但没有给它分配任何内存空间。当执行scanf("%d %s %c%d", &day, cow, &sign, &change);时,%s格式符会试图把输入的奶牛名字写入cow指向的内存地址,但这个指针此时是个野指针(指向随机的、无效的内存区域),直接触发了内存非法访问,也就是你看到的Segmentation fault (core dumped)。
两种修复方案
方案1:使用固定大小的字符数组(C风格)
把char* cow;替换成一个足够容纳奶牛名字的字符数组,比如:
char cow[20]; // 奶牛名字最长是"Mildred"(8个字符),20的大小完全足够
这样scanf就有了合法的内存区域来存储输入的字符串。
方案2:使用C++的string(更安全推荐)
既然你写的是C代码,直接用std::string会更安全、更符合C的风格。修改如下:
// 把char* cow;改成: string cow; // 然后改用cin读取,彻底避免指针问题: cin >> day >> cow >> sign >> change;
用string的话不需要手动管理内存,能彻底避免野指针的问题。
额外的小优化(非段错误原因,但更严谨)
你判断奶牛ID的三个if可以改成else if,避免不必要的判断(虽然题目输入只有三个奶牛,但代码更严谨):
int id; if (cow == "Bessie") id = 0; else if (cow == "Elsie") id = 1; else if (cow == "Mildred") id = 2;
修复后的完整代码示例(用string版本)
#include<bits/stdc++.h> using namespace std; int main(){ freopen("measurement.in","r",stdin); freopen("measurement.out","w",stdout); vector<tuple<int,int,int>> records; int n; scanf("%d", &n); int day; string cow; char sign; int change; for (int i=0;i<n;i++){ cin >> day >> cow >> sign >> change; if (sign == '-') change = -change; int id; if (cow == "Bessie") id = 0; else if (cow == "Elsie") id = 1; else if (cow == "Mildred") id = 2; records.push_back(make_tuple(day,id,change)); } sort(records.begin(),records.end()); int galls[3] = {7,7,7}; vector<int> board {0,1,2}; int num = 0; for (auto record : records){ vector<int> temp = board; galls[get<1>(record)]+=get<2>(record); int max_o = 0; for(int i=0;i<3;i++) max_o = max(max_o,galls[i]); board.clear(); for (int i=0;i<3;i++) if (galls[i] == max_o) board.push_back(i); if (board.size() != temp.size()){ num++; } else{ bool changed = false; for (int i=0;i<board.size();i++){ if (board[i] != temp[i]){ changed = true; break; } } if (changed) num++; } } cout << num; return 0; // 加上return 0更规范,main函数默认会返回0,但显式写出更清晰 }
这个修改后的代码不仅能解决段错误,逻辑也和你原来的完全一致,能正常运行并输出正确结果。
内容的提问来源于stack exchange,提问作者gr3atm4n
相关产品推荐
相关产品推荐

