'C++ rvalue assignment what caused this program to crash but lvalue assignment not
I am studying C++ rvalue reference by example. It was like this:
Intvec::~Intvec()
{
log("destructor");
if (m_data) {
delete[] m_data;
m_data = 0;
}
}
Intvec::Intvec(const Intvec& other)
:m_size(other.m_size), m_data(new int[m_size])
{
log("copy constructor");
for(size_t i = 0; i<m_size; ++i)
m_data[i] = other.m_data[i];
}
Intvec& Intvec::operator=(const Intvec& other)
{
log("copy assignment operator");
Intvec tmp(other);
std::swap(m_size, tmp.m_size);
std::swap(m_data, tmp.m_data);
return *this;
}
Then I changed it to be following. When debugging step by step, it calls delete[] many times until it crashes: read access violation at: 0x3f7a2f91
Intvec& Intvec::operator=(const Intvec& other)
{
log("copy assignment operator");
size_t othersize = other.m_size;
int* otherdata = other.m_data;
std::swap(m_size, othersize);
std::swap(m_data, otherdata);
return *this;
}
I am confused at:
- In example,
Intvec tmp(other)returns a tmporary tmp object, it would be destroyed afterreturn *this, it does not crash. - In my code,
otheris an rvalue, it is also destroyed afterreturn *this, why it crashes because of read access at wrong memory.
It only happens to rvalue, not lvalue.
Intvec v1 = Intvec(10);
Intvec v2;
cout << "assigning lvalue...\n";
v2 = v1;
cout << "ended assigning lvalue...\n";
Intvec v2;
cout << "assigning rvalue...\n";
v2 = Intvec(33);
cout << "ended assigning rvalue...\n";
Solution 1:[1]
For your operator=, after v2 = Intvec(33);, the data member m_data of both v2 and the temporary Intvec point to the same array allocated. Then with the destroy of the temporary and v2, m_data would be deleted twice, which leads to UB.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | songyuanyao |
