You haven't shown any copy constructors. By that, I assume that you are relying on the default copy constructors provided by the compiler. That is the source of your problem.
When you use:
...push_back(Node(this));
in NodeEditor, you are storing a copy of Node(this). However, if Node and NodeIO don't have properly implemented copy constructors, the NodeIO objects in the Node object in the std::vector will point to a Node object that is not valid -- the temporary Node object.
Here's a sample program that shows the problem.
#include <iostream>
#include <vector>
struct Node;
struct NodeIO {
Node* owner;
NodeIO(Node* _owner) : owner{ _owner } { }
};
struct NodeEditor;
struct Node {
NodeEditor* owner;
Node(NodeEditor* _owner) : owner(_owner)
{
std::cout << (void*)this << std::endl;
nodeIOList.push_back(NodeIO(this));
nodeIOList.push_back(NodeIO(this));
}
std::vector<NodeIO> nodeIOList;
};
struct NodeEditor {
NodeEditor()
{
nodeList.push_back(Node(this));
nodeList.push_back(Node(this));
}
std::vector<Node> nodeList;
};
int main()
{
NodeEditor editor;
for ( auto& node : editor.nodeList )
{
std::cout << (void*)(&node) << std::endl;
for (auto& nodeIO : node.nodeIOList )
{
std::cout << (void*)(nodeIO.owner) << std::endl;
}
}
}
Output:
0x7ffe53d34c30
0x7ffe53d34c50
0xae10c0
0x7ffe1af7a2a0
0x7ffe1af7a2a0
0xae10e0
0x7ffe1af7a2c0
0x7ffe1af7a2c0
The output clearly shows the values of the pointers to the Node objects that were constructed using Node(this) and the values of the pointers to the Node objects that are stores in the std::vector<Node>. Please note that the NodeIO objects still point to the temporary Node objects. They are dangling pointers in main.
I tried a quick fix but that did not work. I need to work on that a little bit more.
Here's a solution that works with default copy constructors. It uses std::vector of std::shared_ptrs instead of std::vector of objects.
#include <iostream>
#include <vector>
#include <memory>
struct Node;
struct NodeIO {
Node* owner;
NodeIO(Node* _owner) : owner{ _owner } { }
};
struct NodeEditor;
struct Node {
NodeEditor* owner;
Node(NodeEditor* _owner) : owner(_owner)
{
std::cout << (void*)this << std::endl;
nodeIOList.push_back(std::make_shared<NodeIO>(this));
nodeIOList.push_back(std::make_shared<NodeIO>(this));
}
std::vector<std::shared_ptr<NodeIO>> nodeIOList;
};
struct NodeEditor {
NodeEditor()
{
nodeList.push_back(std::make_shared<Node>(this));
nodeList.push_back(std::make_shared<Node>(this));
}
std::vector<std::shared_ptr<Node>> nodeList;
};
int main()
{
NodeEditor editor;
for ( auto& node : editor.nodeList )
{
std::cout << (void*)(node.get()) << std::endl;
for (auto& nodeIO : node->nodeIOList )
{
std::cout << (void*)(nodeIO.get()->owner) << std::endl;
}
}
}
Output:
0x1460c30
0x1461110
0x1460c30
0x1460c30
0x1460c30
0x1461110
0x1461110
0x1461110
ownermember-variables over to their target-objects.Nodeobject, then theNodeIOsub-objects that the newly-createdNodeobject holds will still haveownermember-variables pointing at the oldNodeobject, which is probably not what you want. (And remember also that data structures like std::vector will make copies of all the objects they hold when they need to resize their internal array larger)std::vectorit will sometimes have to re-allocate it's content to keep it contigous in memory. If that happens pointers and references to those objects will become invalidated. Try using astd::dequeinstead and see it that works for you. Astd::dequenever re-allocates it's content.