Reputation: 727
Why am I getting an access violation reading location 0xC0000005 here if the same code works like a charm when I coding in linux?
if(nodo->izq!=NULL) //nodo is a class or struct and "sig" is a pointer of the same kind
VaciarAux(nodo->izq);
Is there any way of getting this done without that unhandled exception? assert will do the trick?
here is the function
void Arbol<T>::VaciarAux(Nodo<T> * &nodo)
{
if(nodo->izq!=NULL)
VaciarAux(nodo->izq);
if(nodo->der!=NULL)
VaciarAux(nodo->der);
if(nodo->izq == NULL && nodo->der ==NULL)
{
actual = nodo;
nodo=NULL;
delete actual;
contador--;
}
Upvotes: 4
Views: 30099
Reputation: 882776
Most likely because nodo
itself is an invalid pointer. The ->
dereferencing would then cause a problem.
You need to check the things that could possibly affect that value (buffer overflows causing corruption, having set to NULL for some reason).
Note that:
if (nodo->izq != NULL)
does not check if the nodo
variable is NULL but rather if the izq
member of what nodo
points to is NULL.
If you simply want to do nothing if nodo
itself is NULL, you could put at the start:
if (nodo == NULL) return;
but I still think you'd be much better off tracking back to the source of the problem rather than just fixing one symptom.
I think the problem is with the way you are processing the tree. You are effectively doing:
def delTree (node):
if node.left != NULL:
delTree (node.left)
if node.right != NULL:
delTree (node.right)
if node.left == NULL and node.right == NULL:
delete node and whatever else you have to do
The main problem with that is that delTree (node.left)
means that you'll get the exact problem you're seeing if the tree is empty since the first thing you try to do is dereference the NULL root node.
The more usual approach is to first recur the children unconditionally (with a NULL protector) then process the node itself, something like:
def delTree (node):
if node == NULL:
return
delTree (node.left)
delTree (node.right)
delete node and whatever else you have to do
This will correctly handle an empty tree and still correctly delete all children before the parent. And it just looks more elegant, which is one of the reasons to use recursion in the first place :-)
I'll leave it as an exercise for the reader to turn that back into C++.
Upvotes: 6
Reputation: 32538
You may want to look into how you are creating a Nodo
type (i.e., look at its default constructor ... it should have one since it's a class/struct that contains pointers). For instance, if you are not initializing the members of a Nodo
type so that the two pointer members are initially NULL
whenever a Nodo
object is created, then they could have any indeterminant value such that the tests for NULL
values inside of Arbol<T>::VaciarAux
will fail. For instance, a new Nodo
would end up with pointers initialized to some random value, but those random memory values contained in the pointer-members of Nodo
are not valid locations accessible in memory. Then when you test whether the pointers are NULL
, the test comes out false, and you attempt to dereference them in the next recursive call to Arbol<T>::VaciarAux
, causing an access violation.
Upvotes: 0
Reputation: 23266
As pax says it's probably a bad pointer. In Linux there may not be strict virtual memory rules as when running the code somewhere else (also depends on the compiler). So in the Linux case it might be working but it might actually be doing something you don't expect.
Upvotes: 1