繁体   English   中英

为什么我的链表标头指向标头之前的2个项目

[英]Why does my linked list head point to 2 items before the head

所以我试图以非全局形式练习我的C双指针链接列表,并且我感到困惑,为什么s(实际上是头)先指向null,然后再指向一些随机地址,即使我认为我将其移至列表中的第一个节点。

这是我的代码:

typedef struct nodeStruct{
    int               item;
    struct nodeStruct *next;
} Statistician;

void add(Statistician **s, int x);
void displayData(Statistician **s);

int main(int argc, char *argv[]) {
    Statistician *s = NULL;

    add(&s, 3); 
    add(&s, 4);
    add(&s, 5);
    add(&s, 6);
    add(&s, 7);
    add(&s, 8);
    add(&s, 9);
    displayData(&s);

    return 0;
}
void add(Statistician **s, int x){
    Statistician *temp = malloc(sizeof(Statistician));

    temp->item = x;
    temp->next = NULL;

    if(s == NULL){
        s = &temp;
    }
    else{
        Statistician *travel = s;

        while(travel->next!=NULL){
        travel = travel->next;
    }

    travel->next = temp;
   }
 }

 void displayData(Statistician **s){
    Statistician *temp = s;

    printf("List is: ");

    while(temp!=NULL){
    printf("%d ", temp->item);
    temp = temp->next;
    }
 }

我从代码中获得此输出,并且也收到以下警告: List is: 0 43586480 3 4 5 6 7 8 9 [警告]在代码行中从不兼容的指针类型初始化(默认情况下启用)[默认]统计信息* travel = s

在打印数据之前,我总是可以将displaydata移动两次,这样我不想看到的第一个数据就不会消失,但是我想知道为什么它会那样工作。 我也可以忽略这些错误,但我想学习如何解决。

[警告]从不兼容的指针类型初始化(默认情况下启用),此行代码统计师* travel = s

这表示您正在分配不兼容的指针类型。

if(s == NULL){
    s = &temp;
}

这里s并不指向您的head*s是。 所以应该

if(*s == NULL){
*s = temp;
}

然后

Statistician *travel = s;

再次应该

Statistician *travel = *s;

然后在displayData()

void displayData(Statistician **s){
Statistician *temp = *s;

该代码逻辑错误。 你没有用s正确。 就像那样。 您之前的操作没有做任何重要的事情。 您对局部变量进行了一些错误的更改,并将单个指针值分配给了一个双指针。

void add(Statistician **s, int x){
    Statistician *temp = malloc(sizeof(Statistician));

    temp->item = x;
    temp->next = NULL;

    if(*s == NULL){
        *s = temp; //<---change 
    }
    else{
        Statistician *travel = *s; //<--change

        while(travel->next!=NULL){
        travel = travel->next;
       }

    travel->next = temp;
   }
 }

您需要通过检查其retyurn值来检查malloc调用是否失败。 当呼叫失败时,这将使您免于未定义的行为。

另外displayData函数也是错误的。 这将是

 void displayData(Statistician **s){
    Statistician *temp = *s; //<---change

    printf("List is: ");

    while(temp!=NULL){
    printf("%d ", temp->item);
    temp = temp->next;
    }
 }

之前,您有未定义的行为来访问您甚至未分配的内存,或者您没有权限。 这在您的代码中调用了Undefined行为。

清除想法:

在这里,当您传递&s则意味着正在发送s地址,类型为Statistician**的局部变量将保存该地址。 现在,如果不取消引用它,则只需使用本地变量中包含的s的地址即可。 这不是您想要的。 您需要更改要传递的地址。 因此,您可以通过取消引用*s = temp实现它,就像这样。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM