简体   繁体   English

当两个指针都位于同一内存时,为什么必须两次调用“删除”?

[英]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' . 我通过使用new将堆内存分配给指针变量'k' ,并将其复制到另一个指针变量'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; 在那种情况下,我认为这两个变量指向同一个内存,因此"delete"仅一个变量就需要内存。 whatever 'k' or 'd' . 无论'k''d' When I did delete k , however, the 'k' and 'd' point the memory yet. 但是,当我delete k时, 'k''d'指向内存。

So I did delete d , and Abort trap 6 error appeared. 所以我确实delete d ,并且出现了Abort trap 6 error

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 d:0x7fbb56c02ae0
k's : 0x7fbb56c02ae0 k的:0x7fbb56c02ae0
d's : 0x7fbb56c02ae0 d:0x7fbb56c02ae0
k's : 0x7fbb56c02ae0 k的:0x7fbb56c02ae0

Abort trap: 6 中止陷阱:6

I expected that the accessing 'k' and 'd' made the segment error after when I did delete d , because I deleted the Memory! 我希望在delete d之后访问'k''d'导致segment error ,因为我删除了内存!

What am I missing, can someone help me with this ? 我想念的是什么,有人可以帮我吗?

When I did delete k , however, the k and d point the memory yet. 但是,当我delete k时, kd指向内存。

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. 在某些指针上调用operator delete将要求操作系统释放与此指针关联的内存,但不会更改指针本身的值。 k and d simply continue pointing to that same location in memory, which is released in the mean time. kd继续指向内存中相同的位置,同时释放该位置。

That's why sometimes people set a pointer to nullptr after delete -ing it. 这就是为什么人们有时在delete -ing它之后delete指针设置为nullptr的原因。 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. delete某些内容时,并没有破坏内存,只是将其标记为未使用。 (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 . 这样,当您delete指针时,指针在发生这种情况后仍然保持指向物理内存中相同的字节, 但是您不再被允许使用它们 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. 这甚至适用于指针本身:禁止再delete指向delete d内存的任何指针,它立即无效。

If you do use a pointer after it's been delete d, it may appear to work correctly. 如果你使用一个指针它已经后delete d,它可能会出现正常工作。 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: 因此,您的最初想法是正确的:只有两个指针之一恰好需要delete ,事实发生后,不得触摸两个指针中的另一个:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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