C++代码删除特定cout语句后触发SIGSEGV错误问题咨询
错误原因
核心是splitter函数存在数组越界访问的C++未定义行为:
- 内层循环
while(s[end]!=' ')没有对end做边界校验,当输入的测试用例最后一个单词末尾没有空格时,end会持续自增,超出字符串的合法下标范围,访问非法内存触发SIGSEGV。 - 保留
cout<<"here";时程序不崩溃属于巧合:未定义行为的触发表现和程序运行时的内存布局、栈状态强相关,添加输出语句改变了运行时的内存分布,刚好让越界访问没有触发段错误,并不代表代码本身没有问题,此前判断splitter函数运行无问题是错误的。
修复方案
修改splitter函数的内层循环,增加边界校验即可,修改后的代码如下:
#include<bits/stdc++.h> using namespace std; vector<string> splitter(string s) { vector<string>v; int start=0; int end=0; int s_len = s.length(); while(end < s_len) { // 新增边界校验,避免end超出字符串长度 while(end < s_len && s[end] != ' ') { end++; } v.push_back(s.substr(start, end - start)); end++; start = end; } return v; } int main() { string s; getline(cin, s); vector<string> v = splitter(s); map<string, int> m; int flag = 1; for(int i=0; i<v.size(); i++) { m[v[i]] += 1; } map<string, int>::iterator it; for(it = m.begin(); it != m.end(); it++) { string name = it->first; int freq = it->second; if(freq > 1) { flag = 0; cout<<name<<" "<<freq<<endl; } } if(flag == 1){ cout<<"-1"; } return 0; }
如果需要兼容输入中存在连续多个空格的场景,可以在内层循环结束后增加跳过连续空格的逻辑,不会影响本次崩溃问题的修复效果。
内容的提问来源于stack exchange,提问作者Mira Granger
相关产品推荐
相关产品推荐

