I have an exception class called Exception, and I'm invoking a recursive function which gets called approximately 200 times while looping through a map. RecursiveFunction() is part of a class that contains a parameters map (which maps a string to a class param). The class param contains a min, a max, and number of steps between min and max, so that a set of functions can be run with each parameter set. RecursiveFunction() therefore loops through the map to run a set of functions given the 'current' parameters.
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);
}
}
The code above fails after about 120 recursive calls. It seems to be a memory issue, because most of the time it fails on the line:
last--;
The weird thing is that the code runs smoothly in both of the following cases:
bool RecursiveFunction(map<string,param>::iterator current) {
...
if(something_wrong)
throw "";
...
}
or
bool RecursiveFunction(map<string,param>::iterator current) {
...
if(something_wrong) {
Exception exc = Exception("RecursiveFunction()","Something went wrong");
ThrowException(exc); //ThrowException() { throw exc; }
}
...
}
The code isn't hitting the 'throw' so the Exception is not being constructed or copied (confirmed with breakpoints). Why would the existence of a class affect the outcome of a function, if that class isn't getting instantiated in the function?
EDIT:
I was able to reproduce this using a complete example (with 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 );
}
}
}
The run crashed with a Stack Overflow exception. Replacing throw Exception("","");
with throw "";
allowed the program to run to completion. Note: the size of the Exception class had an impact on how big n needed to be in order to overflow. Thanks @catscradle and @Yakk for your comments.