我试图实施单链表。我的addAtLast()函数没有正确执行。程序在执行此功能时崩溃。请提出一些改变。
class LList
{
public:
int noOfNodes;
Node const *start;/*Header Node*/
LList()
{
start=new Node;
noOfNodes=0;start=0;
}
void addAtFront(Node* n)
{
/*
cout<<endl<<"class"<<n;
cout<<"start"<<start;
cout<<"data in node";n->print();
*/
n->next=const_cast<Node*>(start);
start=n;
// cout<<" next=";start->print();
noOfNodes++;
}
void addAtLast(Node* n)
{
Node *cur=const_cast<Node*>(start);
if (start==NULL)
{
start=n;
return;
}
while(cur->next!=NULL)
{
cur=cur->next;
}
cur->next=n;
noOfNodes++;
}
int getPosition(Node data)
{
int pos=0;
Node *cur=const_cast<Node*>(start);
while(cur!=NULL)
{
pos++;
if(*cur==data)
{
return pos;
}
cur=cur->next;
}
return -1;//not found
}
Node getNode(int pos)
{
if(pos<1)
return -1;// not a valid position
else if(pos>noOfNodes)
return -1; // not a valid position
Node *cur=const_cast<Node*>(start);
int curPos=0;
while(cur!=NULL)
{
if(++curPos==pos)
return *cur;
cur=cur->next;
}
}
void traverse()
{
Node *cur=const_cast<Node*>(start);
while(cur!=NULL)
{
// cout<<"start"<<start;
cur->print();
cur=cur->next;
}
}
~LList()
{
delete start;
}
};
答案 0 :(得分:2)
void addAtLast(Node* n) {
Node *cur=const_cast<Node*>(start);
if(start==NULL) {
start=n;
n->next = NULL;
noOfNodes++;
return;
}
while(cur->next!=NULL) {
cur=cur->next;
}
cur->next=n;
n->next = NULL; // Added
noOfNodes++;
}
答案 1 :(得分:1)
从一开始..
start=new Node;
noOfNodes=0;start=0;
这应该是吗?
start=new Node;
noOfNodes=0;start->next=NULL;
你在2行内创造了内存泄漏。我不知道您为什么要设置start=0
。不要这样做,你只是为它分配了记忆!
至于坠机事件,@ liulinhuai的答案解决了这个问题。您将取消引用一个未初始化的指针,试图获取它的next
成员。
答案 2 :(得分:1)
在您的ctor中,您将start设置为0.在崩溃功能中,首先检查NULL
:
if (start==NULL)
{
start=n;
//n->next is now points to nowhere
return;
}
接下来调用addAtLast
迭代,直到找到NULL
,但之前的分配没有将next
指针设置为NULL
,因此第二次迭代将导致access violation
:< / p>
while(cur->next!=NULL) {
//first time it's ok but second call on cur will crash
cur=cur->next;
}
解决方案是 - 所有新的Node
都必须将next
指针设置为NULL
答案 3 :(得分:1)
我在评论中提到了这一点,但在此将作为答案解决。此函数的调用者必须确保两件事:
传入的节点列表( 列表,即使只有一个元素长)必须才能正确终止-pointer设置为NULL。 调用者必须确保这一点,因为此代码无法假定它并盲目地设置node->next = NULL;
确保调用者知道一旦执行,此列表现在拥有传入的节点及其可能启动的任何列表和调用者因此,必须不在呼叫者方面释放它,或者它指向的任何内容。
除了节点计数管理问题之外,addAtLast()
函数没有任何问题,尽管我的实现方式有点不同:
void addAtLast(Node* n)
{
// no nulls allowed
if (n == NULL)
return;
// set start if first in list
if (start == NULL)
{
start = n;
noOfNodes = 1;
}
// else walk list to find end
else
{
Node *cur = const_cast<Node*>(start);
while(cur->next != NULL)
cur = cur->next;
cur->next = n;
++noOfNodes;
}
// adjust count to contain any nodes from 'n'
while (n->next != NULL)
{
++noOfnodes;
n = n->next;
}
}