首页 > 解决方案 > 为什么我的类节点会覆盖自己而不是创建新的节点对象

问题描述

有人可以运行此代码并告诉我为什么插入中的节点不断覆盖?

#ifndef LinkedList_hpp
#define LinkedList_hpp

#include <stdio.h>
#include <utility>

template<class T>class LinkedList{
public:
LinkedList(){
        head = nullptr;
        tail = nullptr;
        size = 0;
    }
    //void insert(T val);
    class Node{
        public:
        Node* next;
        T* value;
        Node* prev;
        Node(T* value){
            this->value = value;
        }
        Node(){
        }
        Node(T* value,Node* prev, Node* next){
            this->value = value;
            this->next = next;
            this->prev = prev;
        }
        Node* operator=(const Node& node){
            this->value = node.value;
            this->prev = node.prev;
            this->next = node.next;
            return *this;
        }

    };
public:
    Node* head;
    Node* tail;
    int size;
    void insert(T val){

在这一行,如果前一个 head 是 10,则当前 val 40 会覆盖旧 head 值并插入一个 val 40 的新节点

        Node* temp = new Node(&val);
        if(head==nullptr){
            head = temp;
            tail = temp;
        }else{
            temp->next = head;
            head->prev = temp;
            head = temp;
        }
        size++;
    }
#endif

#include <iostream>
#include "LinkedList.hpp"

int main(int argc, const char * argv[]) {

   // LinkedList<int> t;
    int h = 7;
    int j = 10;
    int k = 40;
    LinkedList<int>* list1 = new LinkedList<int>();


    list1->insert(h);
    list1->insert(j);
    list1->insert(k);

return 0;
}

每次调用 insert 并构造一个新节点时,它都会覆盖旧值,一切都成为当前 Val

标签: c++listtemplatesoverwrite

解决方案


void insert(T val){

val是这个函数的一个参数。此对象 thisval仅在此函数返回之前存在。此时它会被销毁,就像在函数内的非静态范围内声明的所有其他内容一样。这就是 C++ 的工作原理。一旦insert()回来,就val不再这样了。它不复存在。它去见它的制造者。它变成了一个前对象,不再存在,完全成为过去。

您的insert()函数执行以下操作:

Node* temp = new Node(&val);

您将指向此val参数的指针传递给Node的构造函数,Node然后将指向参数的指针保存为insert(),作为其自己的类成员。

这很好,但是一旦insert()返回,new-ed中保存的指针Node就变成了一个指向被破坏对象的指针,并且取消引用这个指针变成了未定义的行为。

然后,您稍后会尝试取消引用原始指针,该指针不再指向有效对象。

这解释了您的代码中观察到的未定义行为。

底线是您的类和模板的设计存在根本缺陷。Node使用指针没有明显的目的。Node应该简单地存储T为它自己的类成员,作为value, 而不是value指向其他T存在于某处的指针,并且可以随时被销毁,这不受Node's 的控制。

所示代码中的另一个问题是 的两个Node构造函数未能初始化next和指向 的prev指针NULL。这也会导致未定义的行为。


推荐阅读