Function per parameter does not modify variables

1

I built a binary tree class in which I have a bfs function that runs through it. As a parameter this method gets a void (*Op) (node_BT <type> *) function pointer that will be called inside the bfs itself:

#pragma once

////////////////////////////   CLASSE NODE: ÁRVORES BINÁRIAS   ////////////////////////////
template <class type>
class node_BT {
public:
    type data;
    node_BT * right;
    node_BT * left;
    node_BT * father;
    node_BT () {
        right = NULL;
        left = NULL;
        father = NULL;
    }
};

///////////////////////////////////   CLASSE ÁRVORE   ///////////////////////////////////
template <class type>
class BinaryTree {
private:
    int nNodes = 0;

    node_BT <type> * head;

    void lrr ( void ( * Op ) ( node_BT <type> * ) , bool inverso = false ) ;
    void bfs(void (*Op)(node_BT <type> *), bool inverso = false) ;

public:

    node_BT < type > * new_node ( type data , node_BT < type > * dad);

    int insert ( type data);

    void print ( bool inverso = false ) ;

    BinaryTree ( int max_p ) { this->max_p = max_p; };
    ~BinaryTree() {};
};



////////////////////////    FUNÇÕES DA ÁRVORE    ////////////////////////

//////// Função: Gerar novo Node ////////

template < class type >
node_BT < type > * BinaryTree < type > :: new_node ( type data , node_BT <type> * dad) {
    node_BT < type > * nNew = new node_BT < type > ();
    nNew->data = data;
    nNew->father = dad;
    nNew->left = NULL;
    nNew->right = NULL;

    return nNew;
};

//////// Função: Inserir o node gerado na posição adequada ////////

template < class type >
int BinaryTree < type > :: insert ( type data ) {
    if ( nNodes == 0 ) {
        head = new_node( data , NULL );
        nNodes++;
        return 1;
    }
    node_BT < type > * temp = this->head;

    while (true) {
        if (temp->data <= data) {
            if (temp->right == NULL) {
                temp->right = new_node ( data , temp ) ;
                nNodes++;
                return 1;
            }
            else {
                temp = temp->right;
            }
        }
        else {
            if (temp->left == NULL) {
                temp->left = new_node ( data , temp );
                nNodes++;
                return 1;
            }
            else {
                temp = temp->left;
            }
        }
    }
    return 0;
};

//////////// FUNÇÕES: Varrer a Árvore ////////////
//////// Função: Percorrer (com filas) em largura root->left->right ////////
template <class type>
void BinaryTree <type> ::bfs(void (*Op) (node_BT <type> *), bool inverso = false) {

    int f1 = -1, f2 = -1; // posição atual  e  posição final da fila
    node_BT <type> *item = new node_BT <type> [ BinaryTree <type> :: nNodes +1]; // itens da fila

    node_BT <type> *temp = this->head;
    item[++f2] = *temp;

    do{
        if (temp->left != NULL) item[++f2] = *temp->left;
        if (temp->right != NULL) item[++f2] = *temp->right;
        if (f1 != f2) Op(&item[++f1]);
        temp = &item[f1+1];
    } while (f1 != f2);


}


//////// Função: imprimir os nodes ////////
template <class type>
void BinaryTree <type> :: print ( bool inverso = false) {
    //bfs ( pp , inverso );
    bfs(p, inverso);
    cout << endl;
    bfs(pp, inverso);
}
template <class type>
void pp ( node_BT <type> *a ) {
    cout << a->data << endl;
}
template <class type>
void p(node_BT <type> *a) {
    a->data = a->data + 100;
    cout << a->data << endl;
}

int main() {

    //node_BT<double> *a = new node_BT<double>() ;
    BinaryTree<int> b(1000);

    b.insert(5);
    b.insert(-7);
    b.insert(0);
    b.insert(5);
    b.insert(15);
    b.insert(1);
    b.insert(9);
    b.insert(-3);
    b.insert(4);

    b.print();

    getchar();

}
The problem is that the void (*Op) (node_BT <type> *) function pointer of the bfs parameter does not modify the received values, such as Op(&item[++f1]); when Op is a pointer to the void p(node_BT <type> *a) function. When I put only to print, using the pp function, the values print correctly, but the other function ( p ) does not modify the received parameter. I could not understand why this happens.

    
asked by anonymous 23.07.2017 / 06:58

1 answer

1

The p function is by modifying the received values. The problem in the case presented is that the values passed to the function are not being used and the pointer to this data is being lost, causing a memory leak:

template <class type>
void BinaryTree <type> ::bfs(void (*Op) (node_BT <type> *), bool inverso = false) {
    int f1 = -1, f2 = -1; // posição atual  e  posição final da fila
    node_BT <type> *item = new node_BT <type> [ BinaryTree <type> :: nNodes +1]; // itens da fila

    node_BT <type> *temp = this->head;
    item[++f2] = *temp;

    do{
        if (temp->left != NULL) item[++f2] = *temp->left;
        if (temp->right != NULL) item[++f2] = *temp->right;
        if (f1 != f2) Op(&item[++f1]);
        temp = &item[f1+1];
    } while (f1 != f2);
}

Notice that the array allocated and assigned to the variable item is traversed, changed (when Op is pointer to p ) but is simply lost at the end of method bfs . I did not understand the reason for this function but I suggest returning or storing this item variable in a member of the BinaryTree class so that you can later make sure that the values have changed and avoid memory leakage.

    
26.07.2017 / 00:21