LeetCode 150逆波兰表达式求值:为何需先检查长度再用isdigit()?
LeetCode 150 逆波兰表达式求值:运行时错误原因解析
我在做LeetCode 150《逆波兰表达式求值》时,卡了很久没找出代码失效的原因,看答案后发现是调用isdigit()前没检查字符串长度。
原代码
int evalRPN(vector<string>& tokens) { stack<int> nums; int num1, num2, num3; for(string s : tokens){ if(isdigit(s[0])){ nums.push(stoi(s)); continue; } num2 = nums.top(); nums.pop(); num1 = nums.top(); nums.pop(); num3 = 0; if(s == "+"){ num3 = num1 + num2; } else if(s == "-"){ num3 = num1-num2; } else if(s == "*"){ num3 = num1 * num2; } else { num3 = num1 / num2; } nums.push(num3); } return nums.top(); }
修改后的关键判断
只需将顶部的if语句修改为:
if (s.size() > 1 || isdigit(s[0]))
疑问与错误分析
我知道长度大于1的字符串肯定是数字(运算符都是单个字符),但原代码只检查首字符是否为数字为什么会失效?没加长度检查时,我遇到了如下内存错误:
runtime error: reference binding to misaligned address 0xbebebebebebec0ba for type 'int', which requires 4 byte alignment (stl_deque.h)
原因很直白:当遇到负数(比如"-12")时,字符串首字符是'-',isdigit(s[0])会返回false,代码会错误地进入运算符处理分支。此时栈里可能根本没有足够的元素(因为这个负数还没被压入栈),调用nums.top()和nums.pop()时,栈已经为空,这会触发底层容器(stack默认用deque实现)的非法内存访问,也就是你看到的对齐错误。
而先检查s.size() > 1,就能把所有多字符的数字(包括负数)直接归入数字分支,避免错误进入运算符处理逻辑,也就不会出现栈空时的非法内存操作了。
内容的提问来源于stack exchange,提问作者Theta
相关产品推荐
相关产品推荐

