首页 > 解决方案 > 在这里使用删除运算符是否正确我很困惑

问题描述

我只是 C++ 的初学者,今天当我们学习链表时,我的老师向我们展示了如何从链表的前面删除。问题是我不明白为什么我们要删除指针 p,它是静态内存可以'我们不是只用第二个使用动态内存指针的代码来做吗?Head 是 Node 类型对象的动态内存指针

//My teacher code 
template <class T>
void DeleteFront(Node<T>* & head)
{
    // save the address of node to be deleted
    Node<T> *p = head;

    // make sure list is not empty
    if (head != NULL)
    {
        // move head to second node and delete original
        head = head->NextNode();
        delete p;//I didn't understand this line because our p declaration is static 
    }
}
//My suggestion
template <class T>
void DeleteFront(Node<T>* & head)
{
    // save the address of node to temporary dynamic pointer
    Node<T> *temp ;
    temp=new Node<T>(head);

    // make sure list is not empty
    if (head != NULL)
    {
        // move temp to second node which will be showed by head
        temp = head->NextNode();
        delete head;//delete front item
        head=temp;//assign the address of second node to head
    }
}

标签: c++

解决方案


p 未声明为静态的。实际上它是一个局部变量。静态变量只能在类范围内声明,并用关键字标记static
静态变量是可以独立于任何对象访问的变量,并且对类本身有效,对任何对象具有相同的值,甚至没有任何对象。事实并非如此,它是一个非常普通的局部变量,它驻留在堆栈上并保存指向 Node 对象的指针。
当您对该指针调用 delete 时,您删除的是指针指向的内容,而不是堆栈本身的指针对象。当然,指针本身也有一个地址,您可以使用该地址&p并可以将其保存到Node<T>**多变的。虽然没有必要这样做。对堆栈上的对象调用 delete 不起作用。

现在关于代码:

您正在创建一个新节点

Node<T> *temp ;
temp=new Node<T>(head);

这不仅是不必要的,而且实际上您正在泄漏内存,因为您覆盖了指针值或退出函数而不调用delete.
每个 new 都应该有一个相应的删除,至少当指针超出范围时,例如函数的结尾。这条线完全是多余的。初始化指针的更好方法是:

Node<T> *temp = nullptr;

除此之外,你的代码做同样的事情。您的老师将要删除的内容保存到 p 中,这可行但可能看起来不直观,而您保存要保存的内容 ( head->NextNode())。两者都有效。
也是NextNode()一个函数,应该有一个小写的名称。函数的名称也应该暗示它的作用。虽然在这种情况下这很容易知道,但 NextNode 并不是真正的动词/动作。getNextNode()会是一个更好的名字。

为了改进老师的代码,您可以将 p 的声明放入 if 块中,p = head如果列表不为空,则保存以及堆栈操作,但我相信编译器会为您执行此操作。


推荐阅读