【问题标题】:Why does my linked list head point to 2 items before the head为什么我的链表头部指向头部之前的2项
【发布时间】:2017-12-10 10:16:14
【问题描述】:

所以我试图以非全局形式练习我的 C 双指针链表,我很困惑为什么 s——实际上是 head——首先指向 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

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

【问题讨论】:

    标签: c pointers linked-list singly-linked-list double-pointer


    【解决方案1】:

    [警告] 在这行代码中从不兼容的指针类型初始化[默认启用] Statistician *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;
    

    【讨论】:

      【解决方案2】:

      代码逻辑错误。你没有正确使用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;
         }
       }
      

      您需要通过检查它的返回值来检查malloc 调用是否失败。当调用失败时,这将使您免于出现未定义的行为。

      另外displayData函数也是错误的。会是

       void displayData(Statistician **s){
          Statistician *temp = *s; //<---change
      
          printf("List is: ");
      
          while(temp!=NULL){
          printf("%d ", temp->item);
          temp = temp->next;
          }
       }
      

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

      清除思路:

      在这里,当您传递&amp;s 时,这意味着正在发送s 的地址,具有Statistician** 类型的局部变量将保存它。现在,如果您不取消引用它,那么您只需使用包含在局部变量中的 s 的地址。这不是你想要的。您需要更改正在传递的地址。所以你可以通过取消引用 *s = temp 来做到这一点,就像这样。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-30
        • 2021-11-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多