C ++链表实现访问数据

时间:2019-02-04 02:36:18

标签: c++

我在下面有自定义的链接列表实现:

#include<iostream>

using namespace std;


struct Node {
    public:
    int data;
    struct Node *next = NULL;
};


class LinkedList {

    public:
        struct Node *head;
        int length = 0;

        void add(double item);
        void add_2(double item);
        void printLL();

};

void LinkedList::add_2(double item) {

    struct Node *node = new Node();
    node->data = item;
    node->next = head;

    head = node;
    length++;   
}

void LinkedList::add(double item) {
    struct Node node;
    node.data = item;
    node.next = head;
    head = &node;
    length++;
}

void LinkedList::printLL() {
    struct Node *cur_node;
    cur_node =  head;
    int i = 0;
    while (i<length) {
        cout << cur_node->data << " ";
        cur_node = cur_node->next;
        i++;
    }
}

它与下面的驱动程序代码一起正常工作:

int main() {
    LinkedList ll = LinkedList();
    ll.add(212);
    // cout << ll.head->data<<endl;
    ll.add_2(2123); 
    //ll.printLL();
    ll.add_2(2123);
    ll.printLL();
    return 0;
}

当我尝试访问驱动程序代码中的数据时,输出变得混乱:

int main() {
    LinkedList ll = LinkedList();
    ll.add(212);
    cout << ll.head->data<<endl;
    ll.add_2(2123); 
    //ll.printLL();
    ll.add_2(2123);
    ll.printLL();
    return 0;
}

结果:

2123 2123 7339552

预期:

2123 2123 212

为什么从驱动程序代码cout << ll.head->data<<endl访问数据会更改引用。

2 个答案:

答案 0 :(得分:3)

void LinkedList::add(double item) {
    struct Node node;

node是具有自动存储功能的局部变量。具有自动存储功能的对象在作用域的末尾(在这种情况下,在函数的末尾)被自动自动

    head = &node;

您将成员head设置为指向局部变量。函数返回后,指向的节点不再存在,并且指针悬空。通过danging指针进行间接操作具有不确定的行为。

解决方案:摆脱损坏的add函数。您已经有一个有效的add_2函数。但是,您确实会泄漏所有分配的内存。

答案 1 :(得分:1)

您对链表的实现在节点变量使用方面存在问题。它应该是一个指针struct Node * node = new Node。通过此声明和初始化,节点指针将位于堆内存部分中,并且仍位于方法add_2之外。在您的实现中,它在堆栈范围内,并且在方法add_2之外无效。
为了阻止内存泄漏,您需要实现LinkedList的构造函数和析构函数。这样,当LinkedList对象超出范围时,将调用其析构函数并释放由add_2或add分配的动态内存。您可以添加更多方法(例如remove,empty,...)来完成LinkedList。

#include <iostream>

using namespace std;

struct Node {
public:
    int data;
    struct Node *next = NULL;
};


class LinkedList {

public:
    LinkedList() : head(NULL), length(0)
    {

    }
    ~LinkedList()
    {
        struct Node *current = head;
        struct Node *prev = NULL;
        while (current != NULL)
        {
            prev = current;
            current = current->next;
            delete prev;
        }
        length = 0;
    }

    struct Node *head;
    int length = 0;

    void add(double item);
    void add_2(double item);
    void printLL();

};


// modified add is similar to add_2
void LinkedList::add(double item) {
    struct Node *node = new Node();
    node->data = item;
    node->next = head;

    head = node;
    length++;
}

void LinkedList::add_2(double item) {
    struct Node *node = new Node();
    node->data = item;
    node->next = head;

    head = node;
    length++;
}

void LinkedList::printLL() {
    struct Node *cur_node;
    cur_node = head;
    int i = 0;
    while (i < length) {
        cout << cur_node->data << " ";
        cur_node = cur_node->next;
        i++;
    }
}




int main() {
    LinkedList ll = LinkedList();
    ll.add_2(212);
    ll.add_2(2123);
    //ll.printLL();
    ll.add_2(2123);
    ll.printLL();
    return 0;
}