简体   繁体   中英

Why do I have to call “delete” twice when I have each two pointers at same memory?

I allocated the heap memory to a pointer variable 'k' by using new , and copied it in another pointer variable 'd' .

In that case, I thought these two variables point to the same memory, so the "delete" that memory was needed in just one variable; whatever 'k' or 'd' . When I did delete k , however, the 'k' and 'd' point the memory yet.

So I did delete d , and Abort trap 6 error appeared.

Here is my test code.

int* k;
k = new int(5);

int* d = k;

cout<<"d's : "<<d<<endl;
cout<<"k's : "<<k<<endl;

delete d;

cout<<"d's : "<<d<<endl;
cout<<"k's : "<<k<<endl;

delete k;

cout<<"d's : "<<d<<endl;
cout<<"k's : "<<k<<endl;

The result is

d's : 0x7fbb56c02ae0
k's : 0x7fbb56c02ae0
d's : 0x7fbb56c02ae0
k's : 0x7fbb56c02ae0

Abort trap: 6

I expected that the accessing 'k' and 'd' made the segment error after when I did delete d , because I deleted the Memory!

What am I missing, can someone help me with this ?

When I did delete k , however, the k and d point the memory yet.

Invoking operator delete on some pointer will ask the operating system to release the memory associated with this pointer, but doesn't change the value of the pointer itself. k and d simply continue pointing to that same location in memory, which is released in the mean time.

That's why sometimes people set a pointer to nullptr after delete -ing it. In your case, this would have saved you from undefined behavior:

delete d;

d = nullptr;
k = nullptr; // Both must be re-assigned

delete k; // Ok, delete on a nullptr is a no-op

When you delete something, you are not destroying memory, you are just marking it as unused. (You may also run cleanup code contained in destructors, but that's another story.) The memory itself, ie the physical bits and bytes, remain in place just as before.

As such, when you delete a pointer, the pointer still remains pointing to the same bytes in physical memory after the fact but you are not allowed to use them anymore . If you do, anything is allowed to happen. This even applies to the pointer itself: Any pointer that points to delete d memory must not be touched anymore, it's immediately invalid.

If you do use a pointer after it's been delete d, it may appear to work correctly. Or you may crash. Or you may access some other memory object that has been created using the same physical bytes of memory. You simply don't know what will actually happen .

As such, your initial idea is correct: Only exactly one of the two pointers needs the delete , the other of the two must not be touched after the fact:

int* k;
k = new int(5);

int* d = k;

cout<<"d's : "<<d<<endl;
cout<<"k's : "<<k<<endl;

delete d;

// cout<<"d's : "<<d<<endl;    //Undefined behavior, the pointer is invalid now
// cout<<"k's : "<<k<<endl;    //Undefined behavior, k is invalid as well

// delete k;    //Undefined behavior, k is invalid

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM