I am working on a fairly large C++ project which unfortunately doesn't really use C++ to its full potential. Large portions of the code are still plain C wrapped in ridiculous C++ classes.
So I tried to make the code more readable and more safe by introducing some C++ and STL.
However, when I assign a vector to an object member I get a strange crash (debug error to be exact). Imagine this:
class A
{
public:
// Default constructor
A()
{
initialize(std::vector<unsigned long>());
};
A(const std::vector<unsigned long> &data)
{
initialize(data)
};
~A() {};
void initialize(const std::vector<unsigned long> &data)
{
m_data = data;
};
private:
std::vector<unsigned long> m_data;
};
Then somewhere else in the code, I call:
a.initialize(std::vector<unsigned long>());
However, the program terminates du to a debug error: vector iterators incompatible. It happens on this assignment:
m_data = data;
... which should make a copy, which is what I intend to do.
However, if I change this line to:
m_data = std::vector<unsigned long>(data);
... everything works as expected.
My questions are: Why's that? And is this the correct way to initialize an object with an empty vector?
Keep in mind that the class in reality is much bigger and has much more members which are passed, which is why I use an initialize function. And there is also the possibility of passing an already existing array, so I do need to be able to initialize it either empty or with existing data.
EDIT: I have found the cause of the crash. I have found out that the code I'm looking at actually works a bit different:
A *pA = malloc(...); // Not really malloc but a wrapper for a WINAPI-Alloc
// Some stuff happens in between
pA->initialize(std::vector<unsigned long>());
So in fact the constructor of A has never been called and therefore the constructor of the vector member (m_data) also never executeded. That's why assigning a constructor worked while implicitly calling the copy-function crashed, since the destination vector hasn't been constructed yet. Well a lesson learned and more horrible code to improve :)
Thanks!
I don't know why your code crashes with that error, as it looks ok, superficially. Perhaps you should edit your question to include a minimal test case.
However, there are better ways to do initialisation:
class A
{
public:
// Default constructor.
// Relies on the fact that the default constructor for std::vector is
// an empty vector.
A()
{}
// Use the initialisation list.
A(const std::vector<unsigned long> &data)
: m_data(data)
{}
private:
std::vector<unsigned long> m_data;
};