为什么我得到这个错误的输出?

时间:2019-09-01 15:38:57

标签: c list

我创建了这个简单的双向链接列表。 问题是,当我打印所有元素时,即使变量“ a”每次都更改,它们也具有相同的char值。

typedef struct node{
char *name;
struct node *n;
struct node *p;
} N;

N *h=NULL;//head

void insert(char *value){
N *temp=malloc(sizeof(N));
if(h==NULL){
    h=temp;
    temp->name=strdup(value);
}
else{
    N *curr=h;
    while(curr->n!=NULL)
        curr=curr->n;
    curr->n=temp;
    temp->p=curr;
    temp->name=strdup(value);
}
}

void print(){
N *temp=h;
printf("%s\n", temp->name);
while(temp->n!=NULL){
    printf("%s\n", temp->name);
    temp=temp->n;
}
}


int main(){

char a[...];
fgets(a,...)

//there is a while section: every time i enter in it, there is:
char *input=a;
insert(input);
print();
}

所以我期望的是: 狮子 熊 山羊 .... 相反,我得到: 狮子,那 熊 那熊 山羊 山羊 山羊

等...

2 个答案:

答案 0 :(得分:0)

您要为每个列表元素指向相同的内存。这段代码

temp->name=value;

由于结构的定义,仅将指针的复制到temp->name

typedef struct node{
char *name;
struct node *n;
struct node *p;
} N;

name只是一个指针。您需要复制value指向的字符串,而不仅仅是将name指向value(将输入验证和错误检查作为练习供读者使用...):

char *duplicateString( const char *inputString )
{
    char newString = malloc( strlen( inputString ) + 1 );
    strcpy( newString, inputString );
    return( newString );
}

如此

temp->name = duplicateString( value );

只需记住在致电free( temp->name )来释放节点之前先致电free( temp )

just use strdup() if you're on a POSIX system

temp->name = strdup( value );

答案 1 :(得分:0)

有两个问题。首先,您在print()中存在一个错误,该错误阻止了最后一个值的显示。检查temp而不是temp-> n:

void print()
{
    N *temp=h;

    while(temp !=NULL){
       printf("%s\n", temp->name);
       temp=temp->n;
   }
}

您的额外printf()调用(在while循环之前)是为什么第一个值被打印两次的原因。

此外,添加新节点时必须分配p和n。如果不分配它们,就不能假定它们将为NULL。

void insert(char *value)
{
    N *temp=malloc(sizeof(N));
    if(h==NULL){
        h=temp;
        temp->p = NULL;
        temp->n = NULL;
        temp->name=strdup(value);
    }
    else{
        N *curr=h;
        while(curr->n!=NULL)
        curr=curr->n;
        curr->n=temp;
        temp->p=curr;
        temp->n = NULL;
        temp->name=strdup(value);
   }
}

此外,您是否需要将该列表进行双向链接?您永远不会使用p指针。