我在下面有自定义的链接列表实现:
#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;
}
结果:
预期:
为什么从驱动程序代码cout << ll.head->data<<endl
访问数据会更改引用。
答案 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;
}