在每个方法调用上覆盖局部变量指针

时间:2017-01-09 19:19:47

标签: c++ pointers linked-list

我目前正在阅读一本关于数据结构和学习c ++的书。我正在尝试实现一个简单的链表。下面是一些列表的代码,最多可以包含两个元素(为了隔离我的问题)。 出现问题的是指向列表中下一个节点的指针。当我创建一个新的Node实例并创建一个指向它的指针时,指针在每个方法调用上保持不变,因此列表中的所有元素都指向同一个节点。但是,如果我直接创建指针,一切都按预期工作。

我猜测的是,我对指针,引用和new关键字有一些基本的误解。

随意运行以下代码。工作代码已注释掉。

#include <iostream>
using namespace std;

template <typename T> class Node {
public:
    Node(T nvalue) {
        this->value = nvalue;
        this->next = NULL;
    }
    T value;
    Node *next;
};

template <typename T> class LinkedList {
    public:
        Node<T> *head;
        LinkedList() {
            this->head = NULL;
        }
        void append(T newVal) {
            // Correct
            // Node<T>* newNode_ptr = new Node<T>(newVal); // newNode_ptr is different on each call
            // Incorrect!?
            Node<T> newNode = Node<T>(newVal);
            Node<T> * newNode_ptr = &newNode; // newNode_ptr is the same on each call
            cout << "New Node Address: " << newNode_ptr << endl; 
            if (!(this->head)) {
                this->head = newNode_ptr;
                cout << "Value 0: " << this->head->value << endl;
            } else {
                this->head->next = newNode_ptr;
                cout << "Value 0: " << this->head->value << endl;
                cout << "Value 1: " << this->head->next->value << endl;
            }
        }
};

int main() {
    LinkedList<int> list = LinkedList<int>();
    list.append(21);
    cout << "..." << endl;
    list.append(42);
}

请注意,此代码设计不完善(某些内容应该是私有的,应该避免使用using namespace std)。我熟悉python所以这个指针的东西有点压倒性的。感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

var cdSearch = $('#input_search');
var modalSearch = $('#index-search__big__header__input input');
function cdSubmit(event){
    if(event.keyCode == 13 || event.which == 13){
        event.preventDefault();
        if($(modalSearch).is('border-is-danger') && $(cdSearch).is('border-is-danger')){
            alert('something is wrong');
        }
        else if($(modalSearch).val() === '' && $(cdSearch).val() === '') {
            alert('field cant be empty');
        }
        else {
            alert('it works');
        }
        return false;
    }
    return true;
}

这是两者中更正确的方法。 <Component Id="MyService.exe" Guid="5187d4cf-c7b7-4f9e-9f2c-2d0557ecdf5e"> <File Id="MyService.exe" Name="MyService.exe" DiskId="1" Source="$(var.MyService.TargetDir)\MyService.exe" KeyPath="yes" /> <ServiceInstall Id="MyService.exe" Type="ownProcess" Name="MyService.exe" DisplayName="MyService" Description="MyService" Start="auto" Account="LocalSystem" ErrorControl="normal" Vital="yes" /> <ServiceControl Id="MyService.exe" Stop="both" Remove="uninstall" Name="MyService.exe" Wait="yes" /> </Component> 的地址不同,这是正常的,它是您想要的。每个节点都是不同的节点,两个不同的对象不能有相同的地址!没有 Node<T>* newNode_ptr = new Node<T>(newVal); 的版本提供相同的地址,因为您正在堆栈上创建对象。这不起作用,每个节点在newNde_ptr函数结束时被销毁。如果将new的打印部分移动到另一个功能,您将看到异常结果(如果它不会崩溃)。由于您的所有指针都指向相同的地址(在您的情况下),并且在您打印出地址的值成为有效节点时,您不会看到崩溃。但是,这是未定义的行为,可能由于多种原因而发生变化。

free-store(malloc / free堆)和堆栈之间的区别是c ++的基本概念。你应该阅读它here

我看到两个的更正确方法的原因是你仍然需要记住append你的节点。更好的方法是使用std::unique_ptr而不是原始指针来避免使用原始指针鼓励的(也可能是其他)错误。

append