Home > other >  C Vector not changing value after being altered in a method
C Vector not changing value after being altered in a method

Time:11-28

I'm trying to create a class for a node in a directed graph (I don't know much about them so forgive if I've messed up any terms). Whenever I add a pointer to n2 to n1's outNodes vector, I want a pointer to n1 to be added to n2's inNodes vector. I hope that made sense and here is my code.

#include <iostream>
#include <vector>

class Node {
private:
  static int nextId;
  int id;
  std::vector<Node*> ptr_outNodes;
  std::vector<Node*> ptr_inNodes;
public:
  Node() {
    id = nextId  ;
  }

  int getId() {
    return id;
  }

  void setInNodes(Node n) {
    ptr_inNodes.push_back(&n);
  }
  void setOutNodes(Node n) {
    ptr_outNodes.push_back(&n);
    n.setInNodes(*this);
  }

  std::vector<Node*> getOutNodes() {
    return ptr_outNodes;
  }

  std::vector<Node*> getInNodes() {
    return ptr_inNodes;
  }
};

int Node::nextId = 0;


int main() {
  Node n1;
  Node n2;

  n1.setOutNodes(n2);
  std::cout << n2.getInNodes().size();
  return 0;
}

As you can see, I have it set to return the size of n2's inNodes. When I run the program I see that it's size is 0. If I print out the size within the setInNodes method, I get the result 1 which is odd to me. Also, if I change my main function to this:

int main() {
  Node n1;
  Node n2;

  n1.setOutNodes(n2);
  n2.setInNodes(n1);
  std::cout << n2.getInNodes().size();
  return 0;
}

I get the result 1. Adding that line shows that the function is working, so I believe something is going wrong when I call setInNodes() from setOutNodes(). I've been staring at this for the past half hour, so if someone could help me that would be great, thanks!

CodePudding user response:

You are providing the methods setInNodes and setOutNodes with copies of the original Node object. The pointer you're pushing into the vector is the address of that copy, not of the original object.

To push the address of the original Node object, you need to pass a Node-pointer to the function.

Code:

... // Your Node class code

void setInNodes(Node *n) {
  ptr_inNodes.push_back(n);
}
void setOutNodes(Node *n) {
  ptr_outNodes.push_back(n);
  n.setInNodes(this);
}
...

// in the main function:
n1.setOutNodes(&n2);
n2.setInNodes(&n1);

CodePudding user response:

In your code :

void setInNodes(Node n) {
    ptr_inNodes.push_back(&n);
  }
  void setOutNodes(Node n) {
    ptr_outNodes.push_back(&n);
    n.setInNodes(*this);
  }

You're passing Node by value (its a temporary). Then you're adding the pointer to the temporary to you're vector. When you're function (setxxx) goes out of scope, the temporary is destroyed, and hence the stored pointer is a pointer to an invalid object. Accessing/dereferencing the pointer after the function exits is undefined behavior (ie the program can do anything).

As mentioned elsewhere you can either pass in a pointer or a reference.

void setXxNode(Node& node)...

Passing by reference would be my choice, as it requires a value (shows intent). One then adds the address of the reference to the vector, but note that the lifetime of object referred to must exceed that of the object that now holds the pointer.

  • Related