C++代码本地运行正常但LeetCode提交报运行时错误原因排查
问题描述
编写LeetCode最长回文子串题目的C++解答时,同一份代码在本地编辑器运行状态良好、结果正确,但提交到LeetCode平台时触发运行时错误。
提交的问题代码
class Solution { public: string longestPalindrome(string s) { string tmp ="", res = "",emp = ""; int leftptr =0,rightptr=0; while(rightptr < s.size()) { if(leftptr == rightptr || s[rightptr] != s[leftptr]) { if(s[rightptr] == s[rightptr - 1] && s.size()>0) { if(emp.size() == 0) { emp.push_back(s[rightptr - 1]); emp.push_back(s[rightptr]); } else { emp.push_back(s[rightptr]); } } tmp.push_back(s[rightptr++]); } else if(s[leftptr] == s[rightptr]) { tmp.push_back(s[rightptr]); if(res.size() < tmp.size()){ res = ""; res = tmp; tmp = ""; } tmp.push_back(s[++leftptr]); } } if(res.size() > emp.size()) return res; else return emp; } };
平台返回错误信息
Line 1061: Char 9: runtime error: addition of unsigned offset to 0x7fff3d1ffc60 overflowed to 0x7fff3d1ffc5f (basic_string.h)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/basic_string.h:1070:9
错误触发原因
核心问题是字符串下标越界访问,属于未定义行为:
- 触发越界的代码行是
if(s[rightptr] == s[rightptr - 1] && s.size()>0):循环初始状态下rightptr值为0,此时rightptr-1为-1,直接访问s[-1]属于访问字符串合法内存范围外的地址。 - 本地运行环境默认未开启严格的内存越界检测,越界位置的内存值刚好没有触发程序崩溃,因此表现为运行结果正常;LeetCode提交环境开启了UndefinedBehaviorSanitizer内存校验工具,会精准捕获这类越界访问,直接抛出运行时错误。
- 该行的判断顺序存在逻辑漏洞:
s.size()>0的校验放在下标访问操作之后,就算传入空字符串,程序也会先执行下标访问逻辑,校验完全起不到防护作用。
对应修复方案
调整边界判断的顺序,将所有下标合法性校验放在访问操作之前,从根源避免越界:
- 将非空判断
s.size()>0挪到所有下标访问逻辑之前; - 新增
rightptr > 0的前置判断,只有右指针不在起始位置时,才访问前一个下标的字符。
修改后的对应判断代码如下:
// 原错误逻辑 // if(s[rightptr] == s[rightptr - 1] && s.size()>0) // 修复后逻辑 if(s.size() > 0 && rightptr > 0 && s[rightptr] == s[rightptr - 1])
*注意:修复越界问题后,现有代码的回文匹配逻辑仍存在缺陷,无法覆盖单字符输入、中心偏移的奇数长度回文等边界场景,若出现答案错误,可采用标准中心扩展法重写核心匹配逻辑,分别枚举奇数、偶数长度回文的中心位置向两边扩展即可覆盖所有场景。
内容的提问来源于stack exchange,提问作者Muhammad
相关产品推荐
相关产品推荐

