Problem in memory displacement

Asked

Viewed 158 times

0

Good evening everyone, I have been facing a problem regarding free() function in the Dysstroy() method, for memory offset.

After inserting values in the binary tree at first I can even displace through the free() function, but if after this displacement I try to print the tree or try to displace the memory again (To test whether the system bars an attempt to print an empty tree or a new memory offset ), the system throws an exception and aborts.

I have tried several things, but as I have little knowledge about pointers 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;

}
  • 1

    Are you allocating the Nodetree with the operator new, therefore, it should shift with the operator delete. The free() is a command of the language C, to displace the memory obtained by the function malloc().

  • Obg for Gomiero’s help. I switched free(obj) to delete(obj) in the method Stroy(), but the problem still continues, I don’t know what I’m doing wrong.

1 answer

1


Accessing memory after being out of focus, or trying to move the same memory twice, results in undefined behavior. Your membership function BinaryTree::destroy expecting a NodeTree * as argument, then it is not possible to change to where the variable argument is pointing, because here you passes for value, instead of go by reference (obj = NULL does not change the argument, only 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.
    }
}
  • Let me see if I understand, if I modify the header of Stroy by changing this void Stroy(Nodetree * obj), so void Stroy(Nodetre *& obj) I could modify where obj is pointing after using free() ? Obg for Mario’s help !

  • @Rogi93, almost that. For example, in T &x = y;, where T is some kind, x is a reference for the variable y of the same kind T, and it would be the value of that variable that you would be changing (in this case, that variable would be root).

  • @Rogi93, by the way, if you allocate storage space with new, it is necessary to de-link it with delete (and not with free()), otherwise the behaviour is undefined.

  • I was able to solve, I put the method header as follows: void Destroy(Nodetree *&obj). Also, I modified free() by delete(). Very obg for the help Mario !!!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.