C++代码触发Signal 11错误:在线判题系统运行异常排查
段错误(Signal 11)原因分析及修复说明
你的代码在本地短用例正常但在线判题系统报Signal 11(段错误),核心问题出在内存越界访问和未定义行为,具体如下:
1. string::find返回值处理错误
std::string::find如果找不到目标字符,会返回std::string::npos——这是一个size_t类型的常量,值通常是-1转换而来的超大无符号数。原代码直接把这个返回值赋值给int p,然后访问mn[p]:
- 当测试用例中存在
PUSH指令的目标字符不在mn中的情况时,p会是一个远超字符串有效下标的值,直接访问mn[p]会触发内存越界,导致段错误。 - 你本地的短用例刚好每次
PUSH的字符都存在,所以没暴露这个问题,但OJ的测试用例必然包含这种场景。
2. pop_back()的无判断调用
在CHANGE和DELETE分支中,代码直接调用mn.pop_back(),没有先判断mn是否为空:
- 如果
mn是空字符串,pop_back()会触发未定义行为,同样可能导致段错误或其他崩溃。
3. 替换循环实现后解决问题的原因
当你用循环遍历字符串查找字符时,会自然处理“找不到目标字符”的情况(比如遍历结束后不执行后续修改逻辑),不会出现越界访问内存的操作;同时如果你的循环实现中隐含了对字符串非空的判断,也避免了pop_back()的未定义行为,因此问题得到解决。
修复后的代码示例
#include <iostream> #include <string> using namespace std; int main() { string mn; string x; char y; for(int i = 0; i < 2000; i++) { cin >> x; if(x != "DELETE") { cin >> y; if(x == "APPEND") { mn += y; } else if(x == "CHANGE") { if(!mn.empty()) { mn.pop_back(); mn += y; } } else if(x == "PUSH") { size_t p = mn.find(y); if(p != string::npos) { mn[p] = (mn[p] == 'Z') ? 'A' : mn[p] + 1; } } } else { int u; cin >> u; if(!mn.empty()) { mn.pop_back(); } } } cout << mn; return 0; }
内容的提问来源于stack exchange,提问作者user27660648
相关产品推荐
相关产品推荐

