如何解决在递归函数中调用函数时出现“双重释放或损坏”错误
我有一个递归函数solveCountdownProblem,该函数调用evaluateCountdown,它采用反抛光表示法格式的表达式。 validateCountdown在一系列嵌套的for循环中(在solveCountdownProblem中),因此被称为很多次。
// margin and padding i.e: m-1 = margin: 1px; p-1 = padding: 1px;
@each $abbr,$name in ('m': 'margin','p': 'padding') {
@for $i from 1 through 100 {
.#{$abbr}-#{$i} {
#{$name}: 1px * $i;
}
}
}
// margin and paddings in separate directions i.e: mt-1 = margin-top: 1px; pb-1 = padding-bottom: 1px;
@each $abbr,$name in ('t': 'top','r': 'right','b': 'bottom','l': 'left') {
@each $prop,$prop-name in ('m': 'margin','p': 'padding') {
@for $i from 1 through 100 {
.#{$prop}#{$abbr}-#{$i} {
#{$prop-name}-#{$name}: 1px * $i;
}
}
}
}
一段时间后,它可以进行正确的计算,但是最终我遇到了内存错误“双精度释放或损坏(输出)”。我已经使用gdb进行调试,并且它会生成此回溯。
double evaluateCountdown(string rpnIn) {
vector<double> stack;
double a = 0,b = 0;
string token = "";
char arithToken;
for (int i = 0; i < rpnIn.size(); ++i) {
if (rpnIn[i] == ' ') {
if (token != "") {
stack.push_back(stod(token)); // Push number to stack
token = "";
}
} else {
if (find(arithOperators.begin(),arithOperators.end(),rpnIn[i]) != arithOperators.end()) { //if char is arithmetic operator
// Pop two numbers of stack and perform operation
// Push result back into stack
arithToken = rpnIn[i];
a = stack.back(); stack.pop_back(); // pops and removes elements
b = stack.back(); stack.pop_back();
if (arithToken == '+') {
stack.push_back(b+a);
} else if (arithToken == '-'){
stack.push_back(b-a);
} else if (arithToken == '/') {
stack.push_back(b/a);
} else if (arithToken == '*') {
stack.push_back(b*a);
}
} else {
token += rpnIn[i]; //add chars to string
}
}
}
return stack.back();
}
似乎指向“向量堆栈”行;但我不确定为什么会出现内存错误。一旦“ stack”超出范围,析构函数是否会自动取消其分配?
解决方法
如果查看评估的字符串"4 6 5 * + +"
,您会发现最后一个操作+
的操作数不足,并且在代码中,您不会检查stack
之前是否有足够的元素两次致电stack.pop_back()
。您需要添加该检查并采取相应措施。可能最干净的方法是将弹出窗口包装在一个函数中:
double pop( std::vector<double> &stack )
{
if( stack.empty() ) { // throw exception,return NaN or whatever logic of your program requires
...
}
auto r = stack.back();
stack.pop_back();
return r;
}
然后您的代码更短,更干净:
// Pop two numbers of stack and perform operation
// Push result back into stack
arithToken = rpnIn[i];
double a = pop( stack ); // pops and removes elements
double b = pop( stack );
(最好在需要时声明并初始化变量,而不是提前声明)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。