我想创建一个列表来保存名称,但是如果列表中已经有名称,我将忽略具有相同名称的新元素。 我无法添加第二个元素: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)
}
答案 0 :(得分:3)
在insert
中,您忘记将最后一个节点“下一个”指针n
设置为NULL
。
另一个问题是您的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
成员将具有一些“随机”或“垃圾”值(该值为 indeterminate )。
第二个问题应该可以解决,方法是使用调试器捕获崩溃并在temp
调用中看到指针NULL
将是strcmp
。然后重新启动程序并逐行重新执行代码,很容易看出指针何时变为NULL
。了解&&
运算符的工作方式及其short-circuit的性质如何导致总是首先评估左侧的内容也将有助于理解。