删除运算符在什么上下文中引发错误

In what context does the delete operator throw an error?

本文关键字:错误 上下文 运算符 在什么 删除      更新时间:2023-10-16

在我的链表实现中,删除内部类Node实例的帮助程序函数deleteNode(Node*)通过在VS 2015的本地Windows调试器中"触发断点"来引发运行时错误。我小心翼翼地匹配我的newdelete操作员。范围/参考是否发挥了我没有意识到的作用?

即使clear()中存在逻辑错误并且deleteNode()被传递nullptr,它不应该抛出错误来删除nullptr,然后将nullptr分配给自己,对吗?删除有什么问题?

class LinkedList {
public:
    LinkedList() : head(nullptr) {}
    ~LinkedList() { clear(); }
    void push_front() {
        head = createNode(head);
    }
    void clear() {
        Node* current_node = head;
        while (current_node != nullptr) {
            Node* next_node = current_node->next; // buffer
            deleteNode(current_node);
            current_node = next_node;
        }
    }
private:    
    struct Node {
        Node(Node* next)
            : next(next) {}
        Node* next;
    };
    Node* head;
    Node* createNode(Node* next) {
        return new Node(next);
    }
    void deleteNode(Node*& toDelete) {
        delete toDelete; // ***VS 2015 puts breakpoint here***
        toDelete = nullptr;
    }
};
int main() {
    auto A = LinkedList();
    A.push_front();
    A.clear();
    return 0;
}

我已经删除了与错误无关的所有属性和方法。此虚拟代码仍会引发相同的错误。

问题出在您的clear()函数中。你看,你认为因为你编写deleteNode函数的方式,你所有的节点都会在clearnullptr。不幸的是,事实并非如此。您将head复制到 current_node 中,并且 head 的副本(即 current_node)在被删除时变为nullptr,但head仍然是非空的。稍后析构函数尝试再次删除它。对已释放的内存调用 delete 会导致未定义的行为。

要修复,请添加

 head = nullptr;

在你的清除功能结束时

删除运算符在什么上下文中引发错误?

如果析构函数本身引发,则 delete 表达式可以引发子对象的析构函数。但是您应该避免抛出析构函数。

如果尝试删除不指向有效对象的指针,则delete表达式也可能具有未定义的行为。例外是 nullptr ,可以安全删除。意外删除无效指针的典型原因是尝试删除相同的指针值两次,或忘记初始化内存。未定义的行为可能会导致任何事情,包括抛出错误。

删除有什么问题?

您要删除同一指针两次。可以通过检查调试器中的值来验证这一点。