我正在尝试在链接列表中按字母顺序对名称进行排序,但是出现运行时错误。我在这里做错了什么?
#include <iostream>
#include <string>
using namespace std;
struct node{
string name;
node *next;
};
node *A;
void addnode(node *&listpointer,string newname){
node *temp;
temp = new node;
if (listpointer == NULL){
temp->name = newname;
temp->next = listpointer;
listpointer = temp;
}else{
node *add;
add = new node;
while (true){
if(listpointer->name > newname){
add->name = newname;
add->next = listpointer->next;
break;
}
listpointer = listpointer->next;
}
}
}
int main(){
A = NULL;
string name1 = "bob";
string name2 = "tod";
string name3 = "thomas";
string name4 = "kate";
string name5 = "alex";
string name6 = "jimmy";
addnode(A,name1);
addnode(A,name2);
addnode(A,name3);
addnode(A,name4);
addnode(A,name5);
addnode(A,name6);
while(true){
if(A == NULL){break;}
cout<< "name is: " << A->name << endl;
A = A->next;
}
return 0;
}
答案 0 :(得分:4)
您正试图在addnode
中取消引用空指针。在listpointer->name > newname
永远不为真的情况下,listpointer
最终将设置为NULL,然后尝试在下一次listpointer->name > newname
比较中再次取消引用。
...代码中的其他可能的逻辑错误,即。
答案 1 :(得分:1)
我认为错误在于你认为:
if (listpointer == NULL){
temp->name = newname;
temp->next = listpointer;
listpointer = temp;
}
保证listpointer以后永远不会为NULL。但事实并非如此,例如:
void addnode(node *&listpointer,string newname){
node *temp;
temp = new node;
if (listpointer == NULL){
temp->name = newname;
temp->next = listpointer;
listpointer = temp;
}else{
node *add;
add = new node;
while (true){
if( (listpointer) == NULL){
std:cout << "oops (listpointer) == NULL)";
}
if(listpointer->name > newname){
add->name = newname;
add->next = listpointer->next;
break;
}
listpointer = listpointer->next;
}
}
}
将打印出“oops”然后段错误,因为lispointer为NULL并使用 - &gt;在NULL上将导致段错误。这是因为在while(true)循环中,listpointer最终到达结尾并被设置为NULL。然后你得到段错误。
我认为更好的想法是做一些事情:
bool has_inserted;
while ( listpointer != NULL){
if(listpointer->name > newname){
add->name = newname;
add->next = listpointer->next;
has_inserted = true;
break;
}
listpointer = listpointer->next;
}
if(has_inserted == false){
//insert at end of list
}
此代码也会泄漏内存,因为您不会删除使用new创建的内容。你可能想用valgrind运行这个(和其他代码)看看我的意思。
答案 2 :(得分:0)
我对您的代码做了一些修改:
1 - 通过从代码中删除temp来防止内存泄漏。
2 - 你必须保持列表第一个元素的指针。如果你丢失它,你将无法再添加更多项目,也无法打印列表内容。
3 - 代码必须分析是否必须在列表的顶部,中间或末尾插入新项目。如果在顶部,则必须将列表指针更改为它。
所以我修复了这些错误,你的代码现在很好。
请记住,您的main()应调整为在打印项目时不更改列表指针(A)。如果是这样,您将在打印后失去对列表的控制权,并且将无法再访问或删除其节点。如果您在此测试中不关心它,请忘记它。
void addnode(node *&listpointer,string newname){
node *add,
*last,
*current;
add = new node;
add->name = newname;
if (listpointer == NULL){
add->next = listpointer;
listpointer = add;
}else{
current = listpointer;
last = listpointer;
while (current && current->name < newname){
last = current;
current = current->next;
}
if (current == listpointer){
/* Insert before 1st node */
add->next = listpointer;
listpointer = add;
}
else{
/* Insert between last and current
or at the end of the list */
last->next = add;
add->next = current;
}
}
}