Problem in deallocation of memory

0

Good evening guys, I've been facing a problem regarding the free () function in the destroy () method for memory deallocation.

After inserting values into the binary tree at first, I can even deallocate through the free () function, but after this deallocation I try to print the tree or try to deallocate the memory again (To test if the system bar attempts an printing an empty tree or re-deallocating memory), the system throws an exception and aborts.

I have tried many things, but since I have little knowledge about pointers I did not succeed.

Thank you in advance

#pragma once
class NodeTree {

 public:

  int value;
  NodeTree * left;
  NodeTree * right;

  NodeTree() {
    value = 0;
  }

};
#pragma once
#include "NodeTree.h"
#include <iostream>
using namespace std;

class BinaryTree {

public:

NodeTree * root;

BinaryTree() {
    root = NULL;
}


bool isEmpty(NodeTree * obj) {
    return obj == NULL;
}


void clean(int opcao) {

    if (isEmpty(root)) {
        cout << "A arvore ja esta vazia, nao e possivel esvazia-la novamente\n";
        return;
    }

    if (opcao == 1) {
        makeEmpty();
    }
    else {
        destroy(root);
        cout << "A arvore foi esvaziada e a memoria desalocada\n";
    }

}

void makeEmpty() {

    root = NULL;
    cout << "A arvore foi esvaziada\n";
    return;

}


void destroy(NodeTree * obj) {

    if (!isEmpty(obj)) {

        destroy(obj->left);

        destroy(obj->right);

        free(obj);

    }

    obj = NULL;

}



void insert(int num) {

    NodeTree * node = new NodeTree;
    node->value = num;

    insertNeatly(node, root);

}


void insertNeatly(NodeTree * node1, NodeTree *&root1) {

    if (root1 == NULL) {
        node1->left = NULL;
        node1->right = NULL;
        root1 = node1;
    }
    else {

        if (node1->value > root1->value) {
            insertInOrder(node1, root1->right);
        }
        else if (node1->value < root1->value) {
            insertInOrder(node1, root1->left);
        }
        else {
            return;
        }

    }

}



void print(NodeTree * obj) {

    if (obj == NULL)
        return;

    printInOrder(obj->left);

    cout << obj->value << " ";

    printInOrder(obj->right);

}


}; 
#include "stdafx.h"
#include "BinaryTree.h"
#include <iostream>
#include <stdlib.h>
using namespace std;

int main(){

BinaryTree tree;
int sentinela = 0;
int numero;
int opcao;

while (sentinela != 4) {

    system("cls");
    cout << "Opcoes:\n\n1-Inserir ordenadamente\n2-Exibir em ordem\n3-Esvaziar arvore\n4-Sair\n\nOpcao desejada: ";
    cin >> sentinela;

    if (sentinela == 1) {
        system("cls");
        cout << "Digite um numero: ";
        cin >> numero;
        tree.insert(numero);
    }

    if (sentinela == 2) {
        system("cls");
        cout << "Exibicao em ordem: ";
        tree.print(tree.root);
        system("PAUSE");
    }


    if (sentinela == 3) {
        system("cls");
        cout << "Escolha a opcao: 1-Esvaziar / 2- Esvaziar e desalocar memoria: ";
        cin >> opcao;
        tree.clean(opcao);
        system("PAUSE");
    }

}

return 0;

}
    
asked by anonymous 11.05.2018 / 04:56

1 answer

1

Accessing memory after being deallocated, or attempting to deallocate twice the same memory, results in undefined behavior . Its member function BinaryTree::destroy expects NodeTree * as argument, so it is not possible to change where the argument variable is pointing, since here you pass by value , instead of pass by reference ( obj = NULL does not change the argument, just the parameter).

For example:

void destroy(NodeTree *&obj) { //< Note a referência (&)
    if (!isEmpty(obj)) {
        destroy(obj->left); // Passa por referência
        destroy(obj->right); // Passa por referência
        delete obj;
        obj = NULL; // Agora sim, é possível alterar o argumento original.
    }
}
    
11.05.2018 / 18:11