简体   繁体   中英

C++ Access violation?

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--;
    }

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++.

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.

You may want to look into how you are creating a Nodo type (ie, 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM