我有一个名为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的意见。
答案 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*)
。