0

I have an Octree and I have to delete a node searched by it's branch. The program can find the node but I'm struggled with delete it. When I create an object of my Octree and I create some nodes but I don't delete them, then the destructor is delete the Octree :

Octree::~Octree()
{
clear(root);
}

void Octree::clear(node *node){
for (int i = 0; i < 8; i++)
    if (node->child[i])
        clear(node->child[i]);

delete node;
}

But when I'd like to delete a concrete node with this method,

void Octree::deletebranch(int branch) {
node *n = search(branch);
if (n) {
    for (int i = 0; i < 8; i++) {
        if (n->child[i]) {
            delete n->child[i];
            n->child[i] = NULL;
        }
    }
    delete n;
    n = NULL;
}
else {
    printf("There is nothing to delete here");
}
}

I got an exception after the destructor called. Exception thrown: read access violation. node was 0x4.

I was debugging step by step and I found some wierd things. When I create a node I do it this way :

        n = new node;
        n->value = xvalue;
        for (int i = 0; i < 8; i++)
            n->child[i] = NULL;

And it's okay I set the value and the node's value is xvalue and the children are NULL. But after I deleted that node with deletebranch() method my node has changed like this.

  • n 0x00500788 {value=0 child=0x0050078c {0x00000004 {value=??? child=0x00000008 {???, ???, ???, ???, ???, ...} }, ...} } Octree::node * value 0 int
  • child 0x0050078c {0x00000004 {value=??? child=0x00000008 {???, ???, ???, ???, ???, ???, ???, ???} }, 0xfdfdfdfd {...}, ...} Octree::node *[8]
  • [0] 0x00000004 {value=??? child=0x00000008 {???, ???, ???, ???, ???, ???, ???, ???} } Octree::node *
  • [1] 0xfdfdfdfd {value=??? child=0xfdfdfe01 {???, ???, ???, ???, ???, ???, ???, ???} } Octree::node *
  • [2] 0xdddddddd {value=??? child=0xdddddde1 {???, ???, ???, ???, ???, ???, ???, ???} } Octree::node *
  • [3] 0x29122f71 {value=??? child=0x29122f75 {???, ???, ???, ???, ???, ???, ???, ???} } Octree::node *
  • [4] 0x0000a9bd {value=??? child=0x0000a9c1 {???, ???, ???, ???, ???, ???, ???, ???} } Octree::node *
  • [5] 0x004d5228 {value=5249384 child=0x004d522c {0x005007a0 {value=5067304 child=0x005007a4 {0x004fe218 {...}, ...} }, ...} } Octree::node *
  • [6] 0x004fe218 {value=5244832 child=0x004fe21c {0x004d00c4 {value=5235224 child=0x004d00c8 {0x00501968 {...}, ...} }, ...} } Octree::node *
  • [7] 0xdddddddd {value=??? child=0xdddddde1 {???, ???, ???, ???, ???, ???, ???, ???} } Octree::node *
  • this 0x0043f818 {root=0x005006b0 {value=0 child=0x005006b4 {0x00000000 , 0x00000000 , 0x00000000 , ...} } } Octree *

I really don't understand why is that because I have never changed the node after I deleted it. And I think that's why I got that exception in the destructor. How should I delete a node? Maybe try catch?

Here is the header file:

class Octree
{ 
public:
struct node
{
    int value;
    node *child[8];
};

Octree();
~Octree();

void clear(node* node);
int convert(int sorszam);
node* searchandset(int dec, int value);
node *search(int dec);
node* step(node *node, int k);
void Print(node *n)const;
void put(int branch, int value);
void deletebranch(int branch);
node *root;
};
T.dog
  • 91
  • 1
  • 12
  • 2
    Not clear about: *But after I deleted that node with deletebranch() method my node has changed*. Are you looking at a node after it has been deleted. If so this is UB. – Richard Critten May 16 '16 at 11:20
  • I don't know what UB is, but yes, I'm looking every node when the destructor is running and the node which I have deleted has children and value. I have copied the node after it has been deleted above. – T.dog May 16 '16 at 11:29
  • 3
    This needs a [mcve]. E.g. what is the type of `child`? What does `node` look like? Etc. etc. – Angew is no longer proud of SO May 16 '16 at 11:34
  • 1
    @T.dog UB is short for [Undefined Behaviour](http://en.cppreference.com/w/cpp/language/ub). Read also through the external links on that page. UB something that you must be familiar with, if you intend to program in c++. – eerorika May 16 '16 at 11:35
  • Regarding the code that searches for a node and saves it as `n` the subsequent `delete n; n = NULL;` - I hope you realize that last assignment to NULL did nothing to *wherever `n` came from*. I.e. somewhere out there is now sitting a non-NULL-but-dangling pointer sitting in a `child[]` array. When its' containing node destructor fires, it will enumerate `child[]` find that pointer, and invoke `delete` therein. But you already deleted the node, thus your problem, and what you have to fix. – WhozCraig May 16 '16 at 11:39
  • But why `n = NULL;` did nothing? When I only use `delete n;` without `n = NULL;` I got the same exception. But if I understand you I've got a non-NULL pointer somewhere in a node which I've already deleted and when the destructor try to delete it I got that exception. What I don't understand is if I deleted that node, why is the destructor try to delete it again? And how should I set 'n' to NULL to prevent this non-NULL-but-dangling situation? – T.dog May 16 '16 at 12:04
  • @WhozCraig could you please be a little more concrete? – T.dog May 16 '16 at 22:05

0 Answers0