问题描述
我以前有很多在 Java 中使用链表的经验,但我似乎对 C++ 中的这种简单尝试感到困惑.我在运行时遇到分段错误,据我所知,这与分配空指针有关,但我对解决方案不知所措.
感谢大家非常有帮助的回复.代码现在可以工作了,但是尝试在 linksList::addNode 的末尾使用
delete p;
会导致运行时出现分段错误.只是好奇是否有人知道这是为什么?
这是我更新的代码:
#include 使用命名空间标准;类节点{上市:整数数据;节点 * 下一个;节点(int x){数据 = x;下一个 = NULL;}节点(int x,节点* y){数据 = x;下一个 = y;}};类链表{节点*头;上市:链接列表(){头 = NULL;}无效添加节点(整数值){节点 *p;如果(头 == NULL)head = 新节点(值,NULL);别的{p=头;while(p->next !=NULL)p=p->下一个;p->next = 新节点(值,NULL);}}无效打印(){节点 * p;p = 头;而(p != NULL){cout<<p->数据<<"
";p=p->下一个;}}};int main(void){链表测试;test.addNode(4);test.addNode(76);test.addNode(12);测试打印();返回(0);}
首先,在 linkedList::addNode
方法中,你有构造 if (head = NULL)
, 这将结束 assigning 给 head
;您需要 ==
运算符.
二、关于线路:
head = &(Node (value, NULL));
由于一些不直观的原因,这行不通.您将获得对 Node
的引用,但该节点将在方法结束后立即超出范围,并且尝试引用它会导致分段错误.您需要使用 new
运算符(与其他类似行相同):
head = new Node(value, NULL);
如果您添加删除节点的方法,请确保delete
该节点,然后它不会像在 Java 中那样自动进行垃圾收集.
侧边栏: 想想会发生这样的事情:当您执行 Node(value, NULL)
时,您正在使用一个声明如下的临时变量:>
Node hiddenTempNode(value, NULL);
这不会在堆栈上以外的任何地方为对象分配空间——这与在堆栈上为 int
和 Node *
分配空间非常相似.变量.结果,只要你离开方法,对象就消失了,指向它的指针在使用时会做一些奇怪的事情.
第三,注意:您可能希望在单参数构造函数中设置 next = NULL
,以确保它始终具有值.与您的默认构造函数类似.
第四:你的 linkedList::print
方法循环直到 p->next
是 NULL
并打印 的值p->下一个
;如果您想获取第一个和最后一个项目,p->next
的那些出现可能应该更改为 p
.
I have plenty of previous experience with linked lists in Java, but I seem to have confused myself with this simple attempt in C++. I am getting a segmentation fault at runtime, which from what I understand has to do with assigning a null pointer, but I am at a loss for a solution.
Edit: Thank you all for the very helpful responses. The code is now working, but trying to use
delete p;
at the end of linkedList::addNode results in a segmentation fault at runtime. Just curious if anyone knew why that is?
Here is my updated code:
#include <iostream>
using namespace std;
class Node{
public:
int data;
Node * next;
Node(int x){
data = x;
next = NULL;
}
Node(int x, Node * y){
data = x;
next = y;
}
};
class linkedList{
Node *head;
public:
linkedList(){
head = NULL;
}
void addNode(int value){
Node *p;
if(head == NULL)
head = new Node (value, NULL);
else{
p=head;
while(p->next !=NULL)
p=p->next;
p->next = new Node (value, NULL);
}
}
void print(){
Node * p;
p = head;
while(p != NULL){
cout << p->data << "
";
p = p->next;
}
}
};
int main(void){
linkedList test;
test.addNode(4);
test.addNode(76);
test.addNode(12);
test.print();
return(0);
}
First, in linkedList::addNode
method, you have the construction if (head = NULL)
, which will wind up assigning to head
; you want the ==
operator.
Second, about the line:
head = &(Node (value, NULL));
For somewhat unintuitive reasons, this won't work. You'll get a reference to a Node
, but that node will go out of scope as soon as the method ends, and attempts to reference it will lead to a segmentation fault. You need to use the new
operator (same with the other similar line):
head = new Node(value, NULL);
If you add a method for removing a node, make sure to delete
the node then—it won't get automatically garbage-collected like it will in Java.
Sidebar: Think of what happens like this: when you do
Node(value, NULL)
, you're using a temporary variable that's declared like this:Node hiddenTempNode(value, NULL);
This doesn't allocate space for an object anywhere except on the stack—it's very similar to allocating space for an
int
and aNode *
on the stack as separate variables. As a result, as soon as you leave the method, the object disappears and the pointer to it will do weird things when used.
Third, beware: you may want to set next = NULL
in your single-parameter constructor, to ensure that it always has a value. Similarly for your default constructor.
Fourth: your linkedList::print
method is looping until p->next
is NULL
and printing the value of p->next
; those occurrences of p->next
should probably be changed to just p
if you want to get the first and last items.
这篇关于简单的 C++ 链表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!