微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在递归函数中调用函数时出现“双重释放或损坏”错误

如何解决在递归函数中调用函数时出现“双重释放或损坏”错误

我有一个递归函数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 举报,一经查实,本站将立刻删除。