SPOJ PALIN题本地测试正常但提交报SIGABRT错误排查
SPOJ PALIN题提交触发SIGABRT错误的排查
核心崩溃原因
- 长数字转整数时触发未捕获的溢出异常
代码中多处使用stoi()将截取的数字片段转换为32位有符号整数,这类整数的最大存储上限约为21亿(对应10位十进制数)。PALIN题的测试用例允许输入长度极长的数字,当截取的前半段字符串长度超过10位时,stoi()会直接抛出std::out_of_range异常,且代码中没有任何捕获逻辑,直接导致进程异常终止,对应操作系统抛出的SIGABRT信号。
典型触发场景:输入一个20位的偶数长度数字,前半段截取的10位字符串数值超过32位整数上限时,转换过程直接崩溃。 - 冗余整数反转逻辑存在固有溢出风险
代码中自定义的reverse(int a)函数,依赖整数运算实现数字反转,在长数字场景下同样会触发整数溢出。实际上回文的对称拼接完全可以通过字符串反转操作实现,不需要依赖整数运算。
逻辑层面的潜在问题
- 奇数长度数字处理分支存在边界遗漏:当中间位为9、且前半段需要进位时,代码没有覆盖“前半段加1后位数扩展”的场景,这类问题在短输入测试时会被溢出崩溃掩盖,一旦转换逻辑正常运行,后续还会出现计算结果错误。
- 全9场景的字符串修改方式存在越界风险:代码中处理全9数字时,先修改原字符串的字符位,再追加字符拼接结果,当原字符串长度较短时表现正常,但在长字符串场景下,一旦前半段加1后位数变化,会触发索引越界。
- 单字符输入的单独分支和通用逻辑重复,存在分支错位风险。
修正方向
- 全流程使用字符串操作处理数字,取消所有长数字片段的整数转换:
- 比较前半段反转结果和后半段的大小时,直接比较两个等长字符串的字典序即可,无需转成整数。
- 前半段需要加1时,直接对字符串做逐位进位的加法,处理完进位后再拼接对称的后半段。
- 全9场景的处理直接构造新字符串:长度为n的全9数字,对应的下一个回文为
"1" + string(n, '0') + "1",无需修改原字符串的内容。 - 去掉单独的单字符输入分支,统一复用通用回文计算逻辑,减少分支冗余带来的错误。
内容的提问来源于stack exchange,提问作者robokkc
相关产品推荐
相关产品推荐

