You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 14:01:12