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

罗马数字转阿拉伯数字C++程序触发Stack smashing detected错误求助

罗马数字转阿拉伯数字程序栈溢出问题修复

原始代码

#include <iostream>
using namespace std;
int main()
{
    int tablica[9];
    string inputromanum;
    cout << "ROMAN: ";
    cin >> inputromanum;
    int maxindeks;
    bool disablenextcomp = false;
    int readysolution = 0;
    maxindeks = inputromanum.length() - 1;{}{}
    for (int i = 0; i <= maxindeks; i++)
    {
        if (inputromanum[i] == 'M' || inputromanum[i] == 'm')
        {
            tablica[i] = 1000;
        }
        if (inputromanum[i] == 'D' || inputromanum[i] == 'd')
        {
            tablica[i] = 500;
        }
        if (inputromanum[i] == 'C'|| inputromanum[i] == 'c')
        {
            tablica[i] = 100;
        }
        if (inputromanum[i] == 'L' || inputromanum[i] == 'l')
        {
            tablica[i] = 50;
        }
        if (inputromanum[i] == 'X' || inputromanum[i] == 'x')
        {
            tablica[i] = 10;
        }
        if (inputromanum[i] == 'V' || inputromanum[i] == 'v')
        {
            tablica[i] = 5;
        }
        if (inputromanum[i] == 'I' || inputromanum[i] == 'i')
        {
            tablica[i] = 1;
        }
    }
    cout<<endl;
    for(int i4 = 0; i4 <= maxindeks; i4++)
    {
        cout<<"tablica["<<i4<<"] = "<<tablica[i4]<<endl;
    }
    for (int i2 = 0; i2 <= maxindeks; i2++)
    {
        int i5 = i2 + 1;
        if (i5 <= maxindeks)
        {
            //cout<<endl<<"tablica[i2 + 1] = "<<tablica[i2 + 1];
            //cout<<endl<<"tablica[i2] = "<<tablica[i2];
            //cout<<endl<<"tablica[i2 + 1] - tablica[i2] = "<<tablica[i2 + 1] - tablica[i2];
            if (tablica[i2 + 1] - tablica[i2] > 0 && disablenextcomp == false)
            { 
                //cout<<endl<<"readysolution + (tablica[i2 + 1] - tablica[i2]) = "<<readysolution + (tablica[i2 + 1] - tablica[i2])<<endl;
                readysolution = readysolution + (tablica[i2 + 1] - tablica[i2]);
                disablenextcomp = true;
            }
            else
            {
                if(disablenextcomp == false)
                {
                    //cout<<endl<<"readysolution + tablica[i2] = "<<readysolution + tablica[i2]<<endl;
                    readysolution = readysolution +  tablica[i2];
                }
                else
                {
                    disablenextcomp = false;
                }
            }
        }
        else
        {
            if(disablenextcomp == false)
            {
                //cout<<endl<<endl<<"OSTATNI INDEKS";
                //cout<<endl<<"tablica[i2] = "<<tablica[i2];
                //cout<<endl<<"readysolution + tablica[i2] = "<<readysolution + tablica[i2];
                readysolution = readysolution +  tablica[i2];
            }
        }
        i5++;
    }
    cout << endl << readysolution;
}

问题描述

该程序用于罗马数字转阿拉伯数字,多数场景运行正常,但输入MMMCMXCVIII(对应3999)或长串M(如11个M)时,会触发*** stack smashing detected ***: terminated错误,无法继续运行。观察发现错误在数组索引超过10时触发,需求是支持1至5000范围内的罗马数字转换。

问题根源

错误核心是数组越界:代码中声明了固定大小的数组int tablica[9];,仅能存储9个元素。但MMMCMXCVIII长度为11,长串M的长度会更长,遍历输入字符串时,i会超过数组最大索引8,写入了数组之外的栈内存,触发系统的栈溢出保护机制。

修复方案

方案1:用动态容器替代固定数组

将固定数组替换为vector<int>,根据输入字符串长度动态分配空间:

  1. 添加头文件:#include <vector>
  2. 替换原数组声明:vector<int> tablica(inputromanum.length());

方案2:移除数组,直接遍历计算(推荐)

不需要存储每个字符的数值,遍历过程中直接获取当前和下一个字符的数值,实时计算结果,彻底避免数组越界问题:

#include <iostream>
#include <string>
#include <cctype>
using namespace std;

// 辅助函数:获取单个罗马字符对应的数值
int getRomanValue(char c) {
    switch(toupper(c)) {
        case 'M': return 1000;
        case 'D': return 500;
        case 'C': return 100;
        case 'L': return 50;
        case 'X': return 10;
        case 'V': return 5;
        case 'I': return 1;
        default: return 0; // 非法字符处理
    }
}

int main()
{
    string inputromanum;
    cout << "ROMAN: ";
    cin >> inputromanum;
    int readysolution = 0;
    int len = inputromanum.length();
    
    for (int i = 0; i < len; i++) {
        int current = getRomanValue(inputromanum[i]);
        // 处理减法规则(如IV=4、IX=9)
        if (i < len - 1 && current < getRomanValue(inputromanum[i+1])) {
            readysolution -= current;
        } else {
            readysolution += current;
        }
    }
    
    cout << endl << readysolution;
    return 0;
}

方案优势

  • 方案2移除了数组,彻底避免越界风险,代码更简洁
  • 辅助函数统一处理字符转数值,可读性更强
  • 自动处理罗马数字的减法规则,逻辑更清晰

内容的提问来源于stack exchange,提问作者whitehat

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 00:05:32