Hazem Abaza
Hazem Abaza

Reputation: 351

Initializing Vector of Structs in Constructor C++

in Class.h

Struct Node
{
   int ID;
   int position;

}

In class Class.cpp I am initializing vector of structs which leads to core dump error

Class::Class(const branch& branches):mybranches(branches)
{
  for (const auto & branch:mybranches)
  {
    Node* node
    node->ID= branch->ID
    node->position= branch->position

    mynodesvector.push_back(std::move(node));

  }
}

However initializing it like this leads to no error

Class::Class(const branch& branches):mybranches(branches)
{
  for (const auto & branch:mybranches)
  {
    Node node
    node.ID= branch->ID
    node.position= branch->position

    mynodesvector.push_back(&node);

  }
}

I want to know what is the reason for the core dump error with initializing it as pointer to struct.

Upvotes: 0

Views: 127

Answers (2)

mutableVoid
mutableVoid

Reputation: 1516

In addition to the answer of @Stefan Lechner:

The version which throws no direct error has a bug which is likely to blow up whenever you try to modify the values in the mynodesvector: you initialize a struct on the stack and then push its address into a vector. Once an iteration of the for loop has terminated, the Node instance is destructed, but you still have the pointer to it in the vector.

for (const auto & branch:mybranches)
  {
    {
        Node node
        node.ID= branch->ID
        node.position= branch->position

        mynodesvector.push_back(&node);
    }
    // here, Node is dead, but the pointer to it lives on.
  }

In order to find bugs like that that escape your code control I recommend enabling compiler warnings and using appropriate sanitizers.

Upvotes: 0

Stephan Lechner
Stephan Lechner

Reputation: 35154

You do not create/allocate an object to which node* shall point; so dereferencing node leads to undefined behaviour;

Node* node;
node->ID= branch->ID;  // UB here...

However, allocating an object like

Node* node = new Node();
node->ID= branch->ID; 
...

should work.

In your second example, you define a Node-object (and not just a pointer to it). So at least accessing its members is save.

Node node;  // defines a Node-object.
node.ID= branch->ID; //save
node.position= branch->position; // save

Note, however, that you push_back a pointer to an object with block scope; when you dereference this pointer later, the actual object will be out of scope and you get undefined behaviour then.

mynodesvector.push_back(&node);

I'd suggest to have a look at std::shared_ptr<Node>.

Upvotes: 2

Related Questions