Function per parameter does not modify variables

Asked

Viewed 55 times

1

I built a binary tree class in which I have a function bfs that goes all the way through it. As a parameter this method receives a function pointer void (*Op) (node_BT <type> *) that will be called within the bfs:

#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 function pointer void (*Op) (node_BT <type> *) of the parameter bfs does not modify the values received, such as Op(&item[++f1]); when Op is a pointer to the function void p(node_BT <type> *a). When I put only to print, using the function pp, values are printed correctly, but the other function (p) does not modify the received parameter. I could not understand why this happens.

1 answer

1


The function p is rather modifying the received values. The problem in the presented case 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);
}

Realize that the array allocated and assigned to the variable item is covered, modified (when Op is a pointer to p) but is simply lost at the end of the method bfs. I don’t understand the reason for this function but I suggest returning or storing this variable item in a class member BinaryTree so that later you can ensure that the values were yes changed and avoid memory leakage.

  • I managed to solve otherwise, transforming the function into a member function and declaring Op thus: void (BinaryTree<type>::*Op) ( node_BT <type> *) besides using the *item as **item, and when using the function Op, I called her that: (this->*Op)(item[++f1]) Well, that worked out well

Browser other questions tagged

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