I have a recursive search algorithm, and I want to clean up my pointers after each call. However, I return in so many locations, it seems sloppy to put a delete
or free
before every one.
Is there a better way? Does me freeing them all at return of the function mean I should just allocate them on the stack instead of in the heap?
Note this is a parallel search (not shown in code), but the caller will never return before its children. Does this have any additional pitfalls for using the stack?
Example Code (Don't worry about the algorithm here):
//create a new struct state (using new), initialize and return (C style)
new_state()
free_list(state* node)//free a list
double minimax(state* node, state* bestState) {
if (base_case) {
return;
}
state* gb = new_state(); //single node
state* children = new_state(); //head of list
generate_children(children); //fill list
state* current = children; //traverse node
//recurse on child
double result = -minimax(current, gb);
if (case1) {
free(gb);
free_list(children);
return;
}
if (case2) {
//do stuff
}
while(current != NULL){
result = -minimax(current, gb);
if (case1) {
free(gb);
free_list(children);
return;
}
if (case2) {
//do stuff
}
current = current->next;
}
free(gb);
gb = NULL;
//More stuff (with children but not gb)
free_list(children);
return;
}
Here is a small sample of RAII:
First we have a struct
that simply stores your items.
struct FreeAll
{
state* gb;
state* children;
FreeAll(state* g, state* c) : gb(g), children(c) {}
~FreeAll() { free(gb); free(children); }
};
Note that on destruction, the free()
is called on both items. How to use it?
double minimax(state* node, state* bestState)
{
if (base_case) {
return;
}
state* gb = new_state(); //single node
state* children = new_state(); //head of list
// Initialize our small RAII object with the above
// pointers
FreeAll fa(gb, children);
generate_children(children); //fill list
state* current = children; //traverse node
//recurse on child
double result = -minimax(current, gb);
if (case1) {
return;
}
if (case2) {
//do stuff
}
while(current != NULL){
result = -minimax(current, gb);
if (case1) {
return;
}
if (case2) {
//do stuff
}
current = current->next;
}
//More stuff (with children but not gb
return;
}
The local variable fa
is a FreeAll
type. When this local goes out of scope, the destructor of fa
is called which calls free
on both the pointers that were stored in the struct
. Also note the lack of any code at the return points to free the memory. This will be done by fa
when it goes out of scope.
Note this is a simple example, and has none of the sophistication as other methods mentioned, but it gives you the basic gist of the RAII paradigm.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With