Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

vector::push_back on an object without a copy-constructor -- are pointer values lost?

I have a class, Agent, with a member attribute pointer to an object of another class, Form:

Agent.h

...//snip includes
class Agent{
private:
  Form* mvForm_ptr;
  ...
public:
  Agent();
  ~Agent();
  ...//snip additional functionality, but no copy-constructor
};

Agent.cpp

#include "Agent.h"
Agent::Agent(){
  mvForm_ptr = new Form();
}
Agent::~Agent(){
  delete mvForm_ptr;
}
...

As you can see, I do not have an explicit copy-constructor for Agent. Later, I use Agent as follows:

Agent player;
std::vector<Agent> agentsVector;
agentsVector.push_back(player);

This seems to be the cause of a SIGSEGV crash whose error report claims that ~Agent is throwing an EXC_BAD_ACCESS exception. Reading up on vector::push_back here it seems that push_back attempts to copy the passed in value. Since I don't have a copy-constructor in class Agent, what happens to the Form pointer upon an implicit copy attempt? If the pointed-to value is lost in the compiler-generated implicit copy-constructor, would adding an explicit copy-constructor resolve the bad access exception? How should a copy-constructor for class Agent above be implemented? Is this an example of the premise described by the Rule of Three?

like image 940
CCJ Avatar asked Apr 21 '26 21:04

CCJ


2 Answers

what happens to the Form pointer upon an implicit copy attempt?

What happens is that the pointer data member is copied, which means both the original and the copy point to the same object, which in turn means that both of them will attempt to delete it when their life comes to an end. Only one of these deletes can succeed. The other leads to undefined behaviour.

In C++11, you can fix this problem by holding an std::unique_ptr<Form> instead of a raw pointer. In C++03, follow the rule of three.

like image 149
juanchopanza Avatar answered Apr 24 '26 12:04

juanchopanza


Since you did not supply a copy or assignment operator the compiler will generate one for you and the pointer will be copied but not the Form. On every destruction of the Agent your pointer will be freed and you will free the same memory multiple times.

A simple fix would be to use shared_ptr to make sure the Form is only deleted when there are no more agents.

like image 30
Sarien Avatar answered Apr 24 '26 12:04

Sarien



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!