-3

First of all I'd like to understand why I get lines (5) and (6) in the output and not only one of them. Second, why mc1.print() prints valid values? Shouldn't _ms point to undefined place after mc1(&MyStruct(mc2)) because the place where MyStruct was created (in cast operator) was already unwind?

struct MyStruct
{
    int w;
    int h;

    MyStruct()
    {
        cout << "MyStruct" << endl;
    }
    ~MyStruct()
    {
        cout << "~MyStruct: w=" << w << "h=" << h << endl;;
    }
};

class MyClass1
{
public:
    MyClass1(MyStruct* ms)
        :_ms(ms)
    {
        cout << "MyClass1" << endl;;
    }
    ~MyClass1()
    {
        cout << "~MyClass1" << endl;
    }

    void print()
    {
        cout << "print: w=" << _ms->w << "h=" << _ms->h << endl;
    }

    MyStruct* _ms;
};

class MyClass2
{
public:
    MyClass2()
    {
        cout << "MyClass2" << endl;
    }
    ~MyClass2()
    {
        cout << "~MyClass2" << endl;
    }

    operator MyStruct()
    {
        MyStruct ms;
        ms.h = 11;
        ms.w = 22;;
        return ms;
    }
};

int main()
{
    MyClass2 mc2;   
    MyClass1 mc1(&MyStruct(mc2));

    mc1.print();

    return 0;
}

the output is

1.    MyClass2
2.    MyStruct
3.   ~MyStruct: w=22h=11
4.    MyClass1
5.    ~MyStruct: w=22h=11
6.    ~MyStruct: w=22h=11
7.    print: w=22h=11
theateist
  • 13,879
  • 17
  • 69
  • 109
  • What you do results in undefined behaviour, because you dereference a pointer to a temporary value in `print`. It might seem to work or might not. Anything is possible. –  Jan 07 '14 at 07:59
  • 1
    Consider the copy constructor. – Alan Stokes Jan 07 '14 at 08:01

2 Answers2

2

Why there is still valid access to struct after leaving the scope?

There isn't. It isn't valid. You can try to read arbitrary memory addresses, but doing so is not valid". The C++ standard just doesn't say what should happen if you do something "invalid". So your code is allowed to do what you're observing.

jalf
  • 243,077
  • 51
  • 345
  • 550
1

First of all I'd like to understand why I get lines (5) and (6) in the output and not only one of them.

I've no idea. I don't, but since the program has undefined behaviour, anything could happen in principle.

Second, why mc1.print() prints valid values?

It doesn't. It gives undefined behaviour, by printing whatever happens to be in the memory that was once occupied by the dead temporary, if that memory is still accessible. In your case, it just happens that nothing has reused or otherwise invalidated the memory, so you happen to see the values you put there when the temporary was alive.

Shouldn't _ms point to undefined place after mc1(&MyStruct(mc2)) because the place where MyStruct was created (in cast operator) was already unwind?

It points to some memory location which no longer contains a valid object. Typically, the stack frame isn't released until the function returns; and even when it is, the memory typically remains accessible. So accessing a dead object gives you some kind of undefined behaviour, which may not be whatever undefined behaviour you thought it should give.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644