I am writing a function which has many return points (depending on what conditions are true) and it does a bunch of news at different points. At every return point, the set of deletes I need to do are different. And even then, I don’t want to do them at different places. What is a good way to handle this?
Some details: Let us consider a function:
int MainClass::testFunction() {
numThreads++;
char *a = new char[100];
// Some computation with a
if (condition1) {
numThreads--;
return -1;
}
char *b = new char[100];
// Some computation with b
if (condition2) {
numThreads--;
return 42;
}
// Some more stuff.
numThreads--;
}
Now, before return -1, I need to do delete a while before return 42, I need to do delete a; delete b;. And you can imagine how this could get complicated if I had multiple return points.
Here are my solutions:
First solution: Put all deletes at the end of the function, put some labels, store the return value at return points, and use goto (yes, that dirty word!) to jump to appropriate deletes and return after executing those deletes.
In the above example, I could say
superset:
delete b;
subset:
delete a;
numThreads--;
And put goto superset before return 42 and goto subset before return -1.
I don’t like the solution for obvious reasons! 🙂
Second solution: I can build an inner class instance, and do new on variables of that class instance. Like this…
int MainClass::testFunction() {
class Local {
char *a, *b;
Local () : a(NULL), b(NULL) {}
~Local () { if (a != NULL) delete a; if (b != NULL) delete b; }
};
Local l = Local();
l.a = new char[100];
// Some computation with a
if (condition1) {
return -1;
}
l.b = new char[100];
// Some computation with b
if (condition2) {
return 42;
}
}
So, what is the problem? Well, how do I access numThreads variable that was in the method? I want to do numThreads++ in the constructor for Local and numThreads-- in the dtor of Local. If it helps, testFunction is also a member function of another class.
Thanks for reading.
Update: Allocating the array on stack is definitely one possibility, but I have run into stack overflow (ah… the name of this website :-)) doing large allocations on stack (stack size for threads is 2MB by default). What I wanted to address in this question was general resource acquisition and destruction.
Um. You’re WAY overcomplicating this. Just set
aandbto NULL at the beginning. Surround the whole thing with atry / catch. If anything goes wrong, throw something (anything will do). In thecatchblock, calldeleteon all of the variables.deletewill do nothing if the variable is NULL.And if you need to do stuff with return variables, you could theoretically just
throwthe return value (yes, you can throw ints). Then when you’re done cleaning up, just return the thrown value.