删除两个不同指针指向的对象

deleting object pointed to by two differnet pointers

我创建了一个 Node 对象,名为 head 的指针指向它。然后创建另一个名为 newHead 的指针,它指向同一个对象。然后我通过 delete head 删除内存并将 head 重新分配给 nullptr。但是,newHead 指针并未反映此更改。从附带的代码可以明显看出 newHead 不是 nullptr 并且访问成员 value returns 垃圾值。

为了理解这个问题,我已经通过 this post 说明

Also note that you can delete the memory from any pointer that points to it

下面的附加代码显然不是这种情况。此外,我知道使用 smart pointers 肯定是解决问题的一种方法,但在我的应用程序中,我确实需要使用原始指针。

如果能帮助我理解为什么会发生这种情况以及如何解决它,我们将不胜感激。谢谢。

#include <iostream>
using namespace std;

class Node {
public:
  Node(int value) {this->value = value;}
  int value;
  Node* next = nullptr;
};

int main(int argc, char** argv) {
  // create a node object
  Node* head = new Node(5);

  // another pointer pointing to head
  Node* newHead = head;

  // delete the object pointed to by head
  delete head;
  head = nullptr;

  // check if newHead is nullptr
  if (newHead == nullptr) {
    std::cout << "newHead is a nullptr" << std::endl;
  }
  else {
    std::cout << "Head is not a nullptr" << std::endl;
    std::cout << "Node value is: " << newHead->value << std::endl;
  }

  return 0;
}

这两个指针指向同一块内存,nullptr 没有放在那里而不是删除的对象。

head = nullptr; // this is not putting nullptr where the deleted object was!

这就是为什么 newHead 没有指向 nullptr 而是指向已释放的内存。


你想要的是对指针的引用

// CPP program to demonstrate references to pointers. 
#include <iostream> 
using namespace std; 

int main() 
{ 
    int x = 10; 

    // ptr1 holds address of x 
    int* ptr1 = &x; 

    // Now ptr2 also holds address of x. 
    // But note that pt2 is an alias of ptr1. 
    // So if we change any of these two to 
    // hold some other address, the other 
    // pointer will also change. 
    int*& ptr2 = ptr1; 

    int y = 20; 
    ptr1 = &y; 

    // Below line prints 20, 20, 10, 20 
    // Note that ptr1 also starts pointing 
    // to y. 
    cout << *ptr1 << " " << *ptr2 << " "
        << x << " " << y; 

    return 0; 
} 

输出:

20 20 10 20

归功于 geeksforgeeks

相比之下,有

int* ptr2 = ptr1; 
int y = 20; 
ptr1 = &y; 

给予

20 10 10 20

I have created one Node object and the pointer named head is pointing to it. Then another pointer named newHead is created which points to the same object. Then I delete the memory by doing delete head and reassign head to a nullptr. However, this change is not reflected by the newHead pointer. From the attached code it is evident that newHead is not a nullptr and accessing the member value returns garbage value.

没错。在您的代码中没有任何地方可以更改 newHeads 的值,因此它仍然具有与以前相同的值。当然访问成员值是错误的,因为对象已经不存在了

To understand this problem, I have already gone through this post which states that

Also note that you can delete the memory from any pointer that points to it

which is evidently not the case for the attached code below.

为什么这么说?这正是您的代码中发生的事情。你有两个指针指向同一个内存块,你可以使用其中一个来释放它。您使用了其中之一,它已被释放。

Any help in giving me an understanding of why is this happening and how to resolve it will be appreciated. Thank you.

您永远不会更改 newHead 的值,因此它包含与您调用 free 之前相同的值。只有在你调用 free 之后,那个对象不再存在,所以它是一个无用的垃圾值。

不清楚你不明白的地方。释放一块内存后,访问它是错误的。解决方法很简单——不要那样做。在执行 delete head; 之后,headnewHead 都指向不再分配的内存。您将 head 设置为 nullptr,但您没有更改 newHead 的值,因此它仍然指向内存曾经所在的位置。

如果您打算使用 mallocnew,则您有责任跟踪对象的生命周期并且不要在其生命周期之外访问它们。

如果您 delete 一个或多个指针指向的内存,指针值不会改变。您可以通过检查 delete 语句执行前后的值指针来测试这一点。

没有办法(不在某处保存一些元信息)知道有多少指针或哪些指针仍指向某个内存缓冲区。

这个 class 对象(从不同位置指向)所遵循的方法是计算仍然指向缓冲区的指针的数量。当你赋值一个新的引用时,你增加指针,当你删除一个引用时,你减少它,只有当引用指针的计数快到0时,你才真正delete它。

使用这种技术来实现像树或更抽象的动态 classes 并不复杂。几年前,我用它来实现一个 string 类型,它具有 写时复制 语义,允许您在大多数只读字符串上保存复制字符串内容。