我想创建一个列表来保存名称,但如果列表中已经有一个名称,我会忽略具有相同名称的新元素。 我不能添加第二个元素:gdb 说
Program received signal SIGSEGV, Segmentation fault.
0x0000555555554c20 in search (nome=0x5555557576d0 "carl")
at desktop/test.c:*line*
*line* while(strcmp(nome,temp->name)!=0&&f==0){
如果搜索的元素不在列表中,则搜索函数应返回 NULL。
typedef struct node{
char *name;
struct node *n;
} N;
N *h=NULL;
void insert(char *name){
N *temp=malloc(sizeof(N));
if(h==NULL){
h=temp;
temp->n=NULL;
temp->name=strdup(name);
}
else{
N *curr=h;
while(curr->n!=NULL)
curr=curr->n;
curr->n=temp;
temp->name=strdup(name);
}
}
N *search(char *name){
N *temp=h;
int f=0;
if(temp==NULL)
return NULL;
else{
while(strcmp(nome,temp->name)!=0&&f==0){
temp=temp->n;
if(temp==NULL)
f=1;
}
if(f==1)
return NULL;
else
return temp;
}
}
int main(){
char *name=//getting input without problems;
N *temp=esearch(name);
if(temp==NULL)
insert(name);
//this four lines sequence repeats for every input (stdin)
}
insert
您忘记将最后一个节点"next"指针设置为NULL
n
。
另一个问题是您的search
函数不会以正确的顺序检查temp
是否为空指针。
我建议你将代码更改为类似
else
{
while (temp != NULL && strcmp(nome, temp->name) != 0)
{
temp = temp->n;
}
return temp;
}
通过上述更改,如果您从列表的末尾跑出来并且temp
变得NULL
那么循环将结束,您将返回NULL
(在这种情况下temp
将NULL
(。
如果找到该名称,则循环结束,temp
将指向该节点,您将返回该节点。
您拥有的代码将不起作用,因为逻辑 AND (&&
( 将首先执行左侧表达式,然后您将取消引用空指针temp
导致未定义的行为和可能的崩溃。
使用调试器应该很容易找到这两个问题。
第一个问题可以通过使用调试器单步执行代码,同时监视变量及其值来发现。然后应该很容易发现n
成员将具有一些"随机"或"垃圾"值(该值不确定(。
第二个问题应该可以通过使用调试器捕获崩溃并查看指针temp
将在strcmp
调用中NULL
来解决。然后重新启动程序并再次逐行遍历代码,很容易看到指针何时变得NULL
。了解&&
运算符的工作原理及其短路性质如何导致始终首先评估左侧也将有助于理解。