Uchiha_itachi
Uchiha_itachi

Reputation: 103

object working after delete this

I am going through the tutorial from this link. It clearly says in it's second point is that after deleting the object via this, then any member of the deleted object should not be accessed after deletion. But still after deleting the object output is "x = 0 y = 0". Here is my code:

 #include<iostream>
using namespace std;
class Test
{
private:
int x;
int y;
public:
Test(int x = 0, int y = 0) { this->x = x; this->y = y; }
void setX(int a) { x = a; }
void setY(int b) { y = b; }
void destroy() { delete this; }
void print() { cout << "x = " << x << " y = " << y << endl; }
};
int main()
{
Test *obj;
obj = new Test;
obj->destroy();
obj->print();
return 0;
}

Upvotes: 0

Views: 74

Answers (2)

shengy
shengy

Reputation: 9749

As Carlton says, the memory was not overwritten, you can try the following code:

int main()
{
    Test *obj;
    obj = new Test;
    obj->destroy();
    Test *another_obj = new Test(7, 8);
    obj->print();
    return 0;
}

This printed x = 7 y = 8 on my machine, you can play around with the code. It probably will give you different results when you try allocating memory between obj->destroy() and obj->print()

The main point is this is undefined behavior

EDIT:

I debugged the code to illustrate it more clear. you can see at first obj's address is 0x100104aa0, then when delete this was executed, the memory was not changed, but, not changing doesn't mean anything, to your program, this means memory 0x100104aa0 is free to use(there's a point here, if the program is going to write to(allocate) some memory, then it makes no difference if the memory is initialized/cleared or not, so for efficiency, free to use memory are not cleared)

Then when I initialized sss, it was allocated at the same address, with new x and y values, note that after the initialization of sss, obj is still pointing to 0x100104aa0, which happens to be the same address as sss, which is the reason calling obj() gives you x = 7 y = 8.

* thread #1: tid = 0x1386d, 0x0000000100000e08 a.out`main + 72 at t.cpp:19, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000000100000e08 a.out`main + 72 at t.cpp:19
   16   {
   17       Test *obj;
   18       obj = new Test(1, 2);
-> 19       obj->destroy();
   20       Test *sss = new Test(7, 8);
   21       obj->print();
   22       return 0;
(lldb) p obj
(Test *) $5 = 0x0000000100104aa0
(lldb) x $5
0x100104aa0: 01 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00  ................
0x100104ab0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
(lldb) n
Process 5010 stopped
* thread #1: tid = 0x1386d, 0x0000000100000e17 a.out`main + 87 at t.cpp:20, queue = 'com.apple.main-thread', stop reason = step over
    frame #0: 0x0000000100000e17 a.out`main + 87 at t.cpp:20
   17       Test *obj;
   18       obj = new Test(1, 2);
   19       obj->destroy();
-> 20       Test *sss = new Test(7, 8);
   21       obj->print();
   22       return 0;
   23   }
(lldb) p obj
(Test *) $6 = 0x0000000100104aa0
(lldb) x $6
0x100104aa0: 01 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00  ................
0x100104ab0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
(lldb) n
Process 5010 stopped
* thread #1: tid = 0x1386d, 0x0000000100000e4b a.out`main + 139 at t.cpp:21, queue = 'com.apple.main-thread', stop reason = step over
    frame #0: 0x0000000100000e4b a.out`main + 139 at t.cpp:21
   18       obj = new Test(1, 2);
   19       obj->destroy();
   20       Test *sss = new Test(7, 8);
-> 21       obj->print();
   22       return 0;
   23   }
(lldb) x $6
0x100104aa0: 07 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00  ................
0x100104ab0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
(lldb) p sss
(Test *) $7 = 0x0000000100104aa0
(lldb) p obj
(Test *) $8 = 0x0000000100104aa0
(lldb)

Upvotes: 0

Carlton
Carlton

Reputation: 4297

This is undefined behavior. The memory previously allocated to x and y just hasn't been overwritten yet when you call print(). A good practice is to set obj = nullptr; immediately after you delete it.

Upvotes: 3

Related Questions