Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Properly passing pointer from function C++

It crashes on s_r->info because s_r is not pointing on obj2. Function search_recurs() should find the pointer and return result. It should find the right pointer because result points on obj2.

But something happens when returning the result because s_r (where s_r=search_recurs() returns the result) does not point on the same object as result, which should be returned from search.

Output:

W Funkcji search:
Name: zmiana2d
Parameter_a : 5
Parameter_d : 6
adres rzutowanie: 00AFFC50
adres result: 00AFFC50

main:
adres obj2: 00AFFC50
adres s_r: 00AFFB04           //<======= Why is it not 00AFFC50 ? 

CODE:

#include "stdafx.h"

using namespace std;


class Node {
private:

public:
    string name;
    Node *parent;
    vector <Node*> children;


    Node() { name = "noname", parent = NULL; }

    Node(string _name) { name = _name, parent = NULL; }

    Node(Node *_parent) { parent = _parent; }

    Node(string _name, Node *_parent) { name = _name, parent = _parent; }

    Node(Node *_parent, vector <Node*> _children) { parent = _parent, children = _children; }

    Node(string _name, Node *_parent, vector <Node*> _children) { name = _name, parent = _parent, children = _children; }

    virtual ~Node() { cout << "Base Destructor called\n"; }


    void add_parent(Node *wsk) {
        parent = wsk;
    }

    void add_children(Node *child) {
        children.push_back(child);
    }

    void info_node() {
        cout << "Name: " << name << endl;
        cout << "Address: " << this << endl;
        cout << "Parent: " << parent << endl;
    }

};


class A { 
private:
    string name;
    int parameter_a;
protected:

    A() { name = "untitled"; parameter_a = 1; }
    A(string _name) { name = _name, parameter_a = 1; }
    A(string _name, int _parameter_a) : name(_name), parameter_a(_parameter_a) {};

    string info_name() {
        return name;
    }

    int info_parameter_a()
    {
        return parameter_a;
    }

public:

    char info_type() {
        return 'A';
    }

    friend class Leaf;
    friend A* search_recurs_node(Node* root, string name);
    virtual void info() = 0;    
};


class Leaf : public Node { 
private:

public:
    vector<A*> objects;
    Leaf() { name = "noname", parent = NULL; }

    Leaf(string _name) { name = _name, parent = NULL; }

    Leaf(Node *_parent) { parent = _parent; }

    Leaf(string _name, Node *_parent) { name = _name, parent = _parent; }

    Leaf(Node *_parent, vector <Node*> _children) { parent = _parent, children = _children; }

    Leaf(string _name, Node *_parent, vector <Node*> _children) { name = _name, parent = _parent, children = _children; }

    void add_objects_leaf(A* obj) {
        objects.push_back(obj);
    }

};


class X : public A, public Leaf {
private:
    int parameter_x;
public:
    X() : A("dziedziczone_w_X_z_A", 98), parameter_x(99) {};
    X(string _name_x, int _parameter_a, int _parameter_x) : A(_name_x, _parameter_a), parameter_x(_parameter_x) {};


    char info_type() {
        return 'X';
    }


    void info() {
        cout << "Name: " << A::info_name() << endl;
        cout << "Parameter_a : " << A::info_parameter_a() << endl;
        cout << "Parameter_d : " << parameter_x << endl;
    }



};



A* search_recurs_node(Node* root, string name) {


    A* result;
    Leaf* rzutowanie;

    if ((root->children.size()) > 0) {
        for (int i = 0; i < (root->children.size()); ++i) {

            search_recurs_node(root->children[i], name);

        }    
    }
    else if (rzutowanie = dynamic_cast<Leaf*>(root)) {
        for (int i = 0; i < rzutowanie->objects.size();++i) {
            if (rzutowanie->objects[i]->info_name() == name) {
                cout << "W Funkcji search: " << endl;
                rzutowanie->objects[i]->info();
                cout << endl << "adres rzutowanie: " << rzutowanie->objects[i] << endl;
                result = (rzutowanie->objects[i]);
                cout << "adres result: " << result << endl;
                cout << endl;
                return result;
            }
        }
    }


    //return NULL;

};

int main()
{
//

    Node A_node("node_A");
    Leaf X_node("node_X", &A_node);

    A_node.add_children(&X_node);

    X obj1("name d1", 1, 2), obj2("zmiana2d", 5, 6);

    X_node.add_objects_leaf(&obj1);
    X_node.add_objects_leaf(&obj2);


    A* s_r;
    s_r = search_recurs_node(&A_node, "zmiana2d");

    cout << "main: " << endl;
    cout << "adres obj2: " << &obj2 << endl;
    cout << "adres s_r: " << s_r << endl;

    s_r->info();

    cout << endl << "The cause of 90% of programming errors sits in front of the screen" << endl;

    return 0;
}
like image 621
imagran Avatar asked Apr 24 '26 14:04

imagran


1 Answers

Preliminary remark

obj2 is of type X, which inherits from A and from Leaf.

You return a pointer to an A. But the A subobject is embedded in X with Leaf; This is why you could get another address. You should convert it to an X* to be sure to have exactly the same address, whatever the layout of your class:

 X* x_r = dynamic_cast<X*>(s_r);   // you can, because there's a virtual fct
 if (x_r) 
    cout << "adres x_r: "<<x_r<<endl; 
 else cout << "couldn't cast"<<endl; 

By the way, think to add a virtual destructor for any class that has a virtual function.

The root cause of your problem

Your recursive search function doesn't work: you call it recursively, but you're not doing anything with the result. Change as follows:

...
if ((root->children.size()) > 0) {
    for (int i = 0; i < (root->children.size()); ++i) {
        auto a= search_recurs_node(root->children[i], name);  // <== keep response returned
        if (a)                                    // <== if value already found
           return a;                              // <== return it
    }    
}
...

It would be wise to return nullptr at the end of your function (why did you comment it out ?)

Online demo

like image 150
Christophe Avatar answered Apr 27 '26 03:04

Christophe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!