problems with Move constructor and Move overloaded assignment operator?

Your class A has several issues:

  • Your assignment operator don’t handle self assignment and leak:

    A& A::operator=(const A& a)
    {
        std::cout<<"overload operator=\n";
        if (this != &a)
        {
            p = a.p;
            delete[] s;
            s = new char[strlen(a.s) + 1];
            strcpy(s, a.s);
        }
        return *this;
    }
    
  • Your move doesn’t move but copy:

A::A(A&& a) : p(a.p), s(a.s)
{
    a.s = nullptr;
    std::cout << "Move constructor\n";
}

A& A::operator=(A&& a)
{
    std::cout << "Move overload operator=\n";

    if (this != &a) {
        p = a.p;
        delete [] s;
        s = a.s;
        a.s = nullptr;
    }
    return *this;
}

Now, about

A make_A()
{
    A a(2,"bonapart"); // Constructor
    return a;
}

There are several scenario because of potential copy elision (NRVO)
(gcc has flag as -fno-elide-constructors to control that)

if NRVO apply, then a is construct “in-place” so no extra destruction/move happens;

else there is a move constructor and the destruction of a.

A make_A()
{
    A a(2,"bonapart"); // #2 ctor(int const char*)
    return a; // #3 move (elided with NRVO)
} // #4 destruction of a, (elided with NRVO)

int main()
{
    A a1; // #1: default ctor
    a1 = // #5: Move assignment (done after make_A)
      make_A(); // #6: destructor of temporary create by make_A

    
    a1.display();
} // #8: destructor of a1

With NRVO

default ctor
ctor(int const char*)
move assignment
destructor
display
destructor

without NRVO (-fno-elide-constructors)

default ctor
ctor(int const char*)
move ctor
destructor
move assignment
destructor
display
destructor

Demo

For

A a1,a2;
a2 = a1 = make_A();

a1 = make_A(); use move assignment.
a2 = (a1 = make_A()) use copy assignment as move assignment returns (correctly) A&

4
In Move constructor and Move overloaded = operator I used a.s=nullptr; This statement is always used in Move semantics fredoverflow(user) explained something like “now the source no longer owns the object it” but I am not getting it. Because if I did not write this statement still no problem everything works fine. please explain this point

Your issue is that you do copy instead of move.

If you do s = a.s; instead of the copy

s = new char[strlen(a.s) + 1];
strcpy(s, a.s);

then both this->s and a.s would point of same data, and both this and a would free the (same) memory in their destructor -> double free error.

a.s = nullptr; would fix that issue.

Leave a Comment