异常类失败并带有递归函数

时间:2013-07-23 13:03:57

标签: c++ visual-studio-2010 recursion throw

我有一个名为Exception的异常类,我正在调用一个递归函数,它在循环遍历映射时被调用大约200次。 RecursiveFunction()是包含参数map(将字符串映射到类param)的类的一部分。类param包含min和max之间的min,max和步数,以便可以使用每个参数集运行一组函数。因此,RecursiveFunction()循环遍历地图以在给定“当前”参数的情况下运行一组函数。

bool RecursiveFunction(map<string,param>::iterator current) {
   map<string,param>::iterator last = parameters.end();
   last--;
   if( current == last )
       return true;
   else {
       // Do some things
       if(something_wrong)
           throw Exception("RecursiveFunction()","Something went wrong");
       ++current;
       RecursiveFunction(current);
   }
}

上述代码在大约120次递归调用后失败。这似乎是一个内存问题,因为大多数时候它都失败了:

last--;

奇怪的是,在以下两种情况下代码都能顺利运行:

bool RecursiveFunction(map<string,param>::iterator current) {
    ...
    if(something_wrong)
        throw "";
    ...
   }

bool RecursiveFunction(map<string,param>::iterator current) {
    ...
    if(something_wrong) {
        Exception exc = Exception("RecursiveFunction()","Something went wrong");
        ThrowException(exc); //ThrowException() { throw exc; }
    }
    ...
   }

代码未命中'throw',因此未构造或复制Exception(使用断点确认)。如果该类没有在函数中实例化,为什么类的存在会影响函数的结果?

编辑:

我能够使用完整的示例(使用Visual Studio 2010)重现这一点:

#include <iostream>

using namespace std;

class Exception: public std::exception {
private:
    char        gsCallPath[1001];
    char        gsError[1001];
public:
    Exception(const char* sErrorCallPath, const char* sThrownError)
    {
       strcpy(gsError,sThrownError);
       strcpy(gsCallPath,sErrorCallPath);
    }
    ~Exception() {
    }
};

bool RecursiveFunction(int n);

int main() {
    RecursiveFunction(500);
}

bool RecursiveFunction(int n) {

    cout << n << '\n';

    if (n == 0)
        return true;
    else {
        if(false) {
            throw Exception("","");
            //throw "";
        }
        else
        {
            RecursiveFunction( n-1 );
        }
    }
}

运行因Stack Overflow异常而崩溃。用throw Exception("","");替换throw "";允许程序运行完成。注意:Exception类的大小会影响为了溢出需要多大的n。感谢@catscradle和@Yakk的意见。

1 个答案:

答案 0 :(得分:1)

#include <exception>
void f() {
    if (false) {
        throw "";
        //throw std::exception();
    }
    return f();
}
int main() {
    f();
}

查看程序集,似乎该函数为异常对象保留了堆栈空间,如果它被抛出则无关紧要。因此,在""的情况下,此函数保留204个字节(sub esp, 0CCh),如果std::exception,则保留sub esp, 0D4h,即8个字节,即sizeof(std::exception) - sizeof(char*)