链表中的指针未按预期工作

时间:2014-08-17 15:21:46

标签: c++ linked-list

链表的这种实现被打破了。节点[0] .next的地址与节点[1]地址不匹配。所以nodes [1] .next为NULL(默认值)。我在搜索方法中添加了一些地址打印。看起来节点[1]没有被初始化?

#include <iostream>
#include <vector>

using namespace std;

typedef struct Node_T {
    int data;
    Node_T *next;
} Node;

class LinkedList{
    public:
        vector<Node> nodes;
            LinkedList(){
        }

        void insert(int data) {
            Node temp_node;
            temp_node.data = data;
            temp_node.next = NULL;

            size_t len = nodes.size();
            nodes.push_back(temp_node);
            if (len > 0) {
                nodes[len - 1].next = &nodes[len];
            }
        }

        int search(int val){
            if (nodes.empty())
                return -1;

            Node *node_ptr = &nodes[0];

            // Debug
            cout << &nodes[1] << "\n";
            cout << &nodes[0].next << "\n";

            int i = 0;
            do {
                if (node_ptr->data == val) return i;
                    i++;
            } while((node_ptr = node_ptr->next) != NULL);

            return -1;
        }

};

int main()
{
    LinkedList llist;
    llist.insert(1);
    llist.insert(2);
    llist.insert(3);
    llist.insert(4);
    llist.insert(5);
    cout << llist.search(3) << "\n";

    return 0;
}

它告诉我:0x8e6a060 0x8e6a05c -1

3 个答案:

答案 0 :(得分:3)

vector添加元素时,对向量元素的引用(以及因此地址)无效。因此,您必须不使用&nodes[0]&nodes[len]等值,因为它们毫无意义。

答案 1 :(得分:3)

这样的练习要点就是将内部结构挂在链表中。您已使用vector<Node>替换了该内部结构。

而不是矢量,我们的想法是拥有

private:
    Node* head;

作为数据成员。

在插入函数中,您应该使用

为节点动态分配内存
Node* newNodePointer = new Node;

用下一个操作指针。

值得指出的是,这可以作为一种练习,但你的真实&#34;代码应该使用标准库设施。

答案 2 :(得分:2)

首先,您的打印输出不正确:此行

cout << &nodes[0].next << "\n";

打印next的地址,而不是打印next本身。改为

cout << nodes[0].next << "\n";

给出正确的打印输出(demo)。

但是,主要问题是您保留指向std::vector元素的指针。这些在第一次写入后变为无效,因为新存储被分配给不断增长的向量。

您当然可以通过预先留出足够的空间(从列表的构造函数调用nodes.reserve(1000); demo)解决此问题,但这只是一个黑客攻击:您应该使用newdelete手动分配链接列表的元素。这就是这项工作的重点。

  

但是我仍然需要一个容器来确保节点按预期生效?

不,你没有。您的班级 是一个容器。通过从头指针引用整个节点链,它可以确保整个链保持“实时”。