Consider the following class:

struct MyClass {
    int mId;
    MyClass(int id): mId(id) {}
   ~MyClass() { std::cout << "deleting: " << mId << std::endl; }
};

And the usage:

std::shared_ptr<MyClass> p(new MyClass(0));
MyClass& m = *p;
m = MyClass(2);

The result is:

deleting: 2
deleting: 2

Please help me understanding:

  1. Why there are two MyClass(2) objects (assumption made on the destructor logs)
  2. Is this a memory leak? Shouldn't the MyClass(0) leak?

Thank you.

有帮助吗?

解决方案

There is no memory leak. This code:

m = MyClass(2);

creates a temporary object of type MyClass which is copied into m using the (default-generated) copy assignment operator of MyClass, and then destructed. Eventually, p runs out of scope and its destructor destroys the MyClass instance to which is points (the one bound to m).

If we spelled out all the implicit calls explicitly, this is happening:

// std::shared_ptr<MyClass> p(new MyClass(0));
tmp1.MyClass(0);
p.shared_ptr(&tmp1);

// MyClass& m = *p;
p.operator* ();

// m = MyClass(2);
tmp2.MyClass(2);
m.operator= (tmp2);
tmp2.~MyClass();

// p goes out of scope
p.~shared_ptr();
tmp1.~MyClass();

其他提示

Do this for a more clear picture of creation destruction:

struct MyClass {
    int mId;
    MyClass(int id): mId(id) {std::cout << "Creating: " << this << "(" << mId << ")\n";}
   ~MyClass()                {std::cout << "Deleting: " << this << "(" << mId << ")\n";}
    MyClass(MyClass const& c)
                             {std::cout << "Copy:     " << this << "(" << mId << ")\n"
                                           "    From: " << &c   << "(" << c.mId << ")\n";
                              mId=c.mId;
                             }
    MyClass& operator=(MyClass const& c)
                             {std::cout << "Assign:   " << this << "(" << mId << ")\n"
                                           "    From: " << &c   << "(" << c.mId << ")\n";
                              mId=c.mId;
                             }
};

When I run I get:

Creating: 0x7fc741c000e0(0)
Creating: 0x7fff50ac38c0(2)
Assign:   0x7fc741c000e0(0)
    From: 0x7fff50ac38c0(2)
Deleting: 0x7fff50ac38c0(2)
Deleting: 0x7fc741c000e0(2)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top