简体   繁体   English

如何删除节点指针

[英]How to delete a node pointer

This is schoolwork. 这是功课。 I haven't seen anything that really answers this directly, so I'm having a hard time fixing it. 我还没有看到任何可以直接回答这个问题的东西,因此我很难解决它。 I have to create a linked node implementation of a max heap and I'm having difficulty with the deletion of a node after removing a value. 我必须创建一个最大堆的链接节点实现,并且在删除值后很难删除节点。

My Code: 我的代码:

template<class ItemType>
BinaryHeapNode<ItemType>* LinkedMaxHeap<ItemType>::getLastNode()
{
    BinaryHeapNode<ItemType>* lastNode = rootPtr->getRightSiblingPtr();
    BinaryHeapNode<ItemType>* prevLastNode = rootPtr;
    while(lastNode != nullptr)
{
    prevLastNode = lastNode;
    lastNode = lastNode->getRightSiblingPtr();      
}
return prevLastNode;
}

template<class ItemType>
bool LinkedMaxHeap<ItemType>::removeValue(ItemType value)
{
    BinaryHeapNode<ItemType>* tempNode = rootPtr;
    for (int i = 0; i < itemCount; i++)
    {
        if(tempNode->getItem() == value)
        {
            tempNode->setItem(getLastNode()->getItem());//set item
            delete getLastNode();                       //delete last node
            getLastNode() = nullptr;                    //set last node null
            getLastNode()->setRightSiblingPtr(nullptr); //last node should be different
            itemCount--;                                //set it's sibling to null
            heapRebuild(tempNode);
        }

        tempNode = tempNode->getRightSiblingPtr();
    }

    return true;
}

My issue is with getLastNode() = nullptr. 我的问题是与getLastNode()= nullptr。 VS is telling me that getLastNode() isn't an lvalue. VS告诉我getLastNode()不是左值。 That doesn't make sense to me because getLastNode is returning a pointer to a BinaryHeapNode, but it can't set that pointer to nullptr? 这对我来说没有意义,因为getLastNode返回指向BinaryHeapNode的指针,但是它不能将该指针设置为nullptr吗?

I thought this might be a problem with my logic of pointers (which is shaky at best) so I thought changing getLastNode() to return just a node would help. 我认为这可能是我的指针逻辑问题(充其量是摇晃的),所以我认为更改getLastNode()以仅返回一个节点会有所帮助。 That did not. 那没有。 So I tried messing with the & operator and returning an address of the last node. 因此,我尝试弄乱&运算符并返回最后一个节点的地址。 Needless to say I haven't found the solution yet. 不用说我还没有找到解决方案。 If anyone can provide some sort of direction it would be appreciated. 如果有人可以提供某种指导,将不胜感激。 I'm just not entirely sure why it doesn't work. 我只是不太确定为什么它不起作用。

EDIT: 编辑:

Edited the code based on what arynaq mentioned. 根据arynaq提到的内容编辑了代码。 The errors went away, but now I have a bunch of linker errors I have to fix before I can test it. 错误消失了,但是现在我遇到了很多链接器错误,在测试之前必须修复。 Will this code do what I want? 这段代码会做我想要的吗? I feel like it is just going to delete nodeToDelete and not get rid of the node in the heap. 我觉得这只是要删除nodeToDelete而不是摆脱堆中的节点。

template<class ItemType>
bool LinkedMaxHeap<ItemType>::removeValue(ItemType value)
{
    BinaryHeapNode<ItemType>* tempNode = rootPtr;
    BinaryHeapNode<ItemType>* nodeToDelete = getLastNode();
    for (int i = 0; i < itemCount; i++)
    {
        if(tempNode->getItem() == value)
        {
            tempNode->setItem(nodeToDelete->getItem());
            delete &nodeToDelete;
            nodeToDelete = nullptr;
            getLastNode()->setRightSiblingPtr(nullptr);
            itemCount--;
            heapRebuild(tempNode);
        }

        tempNode = tempNode->getRightSiblingPtr();
    }

    return true;
}

Ok, I'll try to help by explaining some things about pointers. 好的,我将通过解释一些有关指针的方法来帮助您。 Hopefully this will clarify some misconceptions and help you with your assignment. 希望这会澄清一些误解,并帮助您完成任务。

When you get a copy of the pointer like so: mypointer* p = get_pointer(); 当您像这样获得指针的副本时: mypointer* p = get_pointer(); and then you delete that, you are deleting the memory. 然后删除它, 删除内存。 But when you assign nullptr to this local variable, it wont affect the "source" of your pointer. 但是,当您将nullptr分配给此局部变量时,它不会影响指针的“源”。

Here is a detailed example, showing where things can go wrong. 这是一个详细的示例,显示了哪里可能出错。 If you never set v[0] to nullptr . 如果您从未将v[0]设置为nullptr

#include <iostream>
#include <vector>

struct Object {
    ~Object() {
        std::cout << "Object destructor." << std::endl;
    }
    int val = 42;
};

struct OtherObj {
    int val = 322;
};

void print_vec(const std::vector<Object*>& v) {
    for (const auto& x : v) {
        std::cout << x << std::endl;
    }
}

int main(int, char**) {
    // Init vector and print addresses.
    std::vector<Object*> v(2);
    print_vec(v);

    // Init objects in vector and printit.
    for (auto& x : v) {
        x = new Object();
    }
    print_vec(v);

    // Get a copy of a pointer and delete that. All good so far.
    Object* pointer_to_delete = v[0];
    delete pointer_to_delete;

    // Assign nullptr to the temporary local pointer.
    // Does nothing to the pointer in the vector.
    pointer_to_delete = nullptr;

    // Print the vector to prove it.
    print_vec(v);

    // On a non debug build, the memory will still have the last value.
    // Careful! Cause of headaches here. This should be set to nullptr.
    std::cout << v[0]->val << std::endl; // "No problem", certainly not nullptr.

    // Now that we allocate a new object, v[0] will be overwritten.
    OtherObj* bad_bad_boy = new OtherObj();
    // Print the address of the new object, to show it was created at
    // the old v[0] address.
    std::cout << bad_bad_boy << std::endl;

    // Bad things ensue...
    std::cout << v[0]->val << std::endl;

    return 0;
}

The output on clang is : lang的输出是:

0x0
0x0
0x7ffa21c026c0
0x7ffa21c026d0
Object destructor.
0x7ffa21c026c0
0x7ffa21c026d0
42
0x7ffa21c026c0
322

As you can see, setting the local pointer to nullptr is not enough! 如您所见,仅将本地指针设置为nullptr是不够的! I hope this clears up some things for you :) 我希望这可以为您解决一些问题:)

Online version 在线版

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

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