C链接列表错误未正确链接

时间:2018-04-24 07:49:10

标签: c pointers logic

我在网上找不到类似的问题,主要是因为我的问题更具体一点,可能是某种逻辑错误造成的。

我试图逐个阅读(已经完成)并创建一个链表(使用typedef,已经完成),它存储了这些单词的所有实例及其频率。

我发现代码的第一部分是链接列表的初始化,然而,程序在尝试链接更多节点后很快就崩溃了。

以下是使用输入运行代码时发生的情况:

C:\path-->test
hello
First word found: hello
head->word = hello
C:\path--> (Program crashes at this point)

我的代码: (我有一个头文件,但我决定将所有内容放在.c文件中以简化)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
struct LinkedList {
        char* word;
        int count;
        struct LinkedList *next;
};

typedef struct LinkedList *list;
int getNextWord(char* output);
list createNode();
void addEntry(list head, char *entry);
void printList(list head);
void insert(char* dest, char* toAdd);
int compare(char* str1, char* str2);

int main(){
  int length;
  char line[5000];
  list head = NULL;
  while(length = getNextWord(line) > 0){
    printf("First word found: %s\n", line);
    addEntry(head, line);
  }
}


void addEntry(list head, char* entry){
  list temp, p;
  temp = createNode();
  if(head == NULL){
    head = temp;
    insert(head->word, entry);
    printf("head->word = %s", head->word);
    p->next->word = NULL;
    return;
  }
  else{
    p = head;
    printf("Inside else in addEntry");
    while(p->next != NULL){
      if(compare(p->word, entry) == 0){
        p->count = p->count + 1;
        return;
      }
      if(compare(p->word, entry) != 0 && p->word != NULL){
        p = p->next;
      }
      if(compare(p->word, entry) != 0 && p->word == NULL){
        insert(p->word, entry);
        p->count = p->count + 1;
        return;
      }
    }
    p->next = temp;
  }
  return;
}

/* Helper function that creates a node of type (list) */
list createNode(){
  list temp;
  temp = (list)malloc(sizeof(struct LinkedList));
  temp->next = NULL;
  return temp;
}
/*list addEntry(list head, char *entry){
  list temp, p;
  temp = createNode();
  if(head == NULL){
    printf("in addEntry head == NULL\n");
    head = temp;
    insert(head->word, entry);
  }
  else {
    printf("in first else case in addEntry\n");
    p = head;
    if((compare(entry, p->word)) == 0 && p->next != NULL){
      p->count = p->count + 1;
      while(0){
        p = p->next;
        if(p->next == NULL){
          p->next = temp;
          return;
          break;
        }
      }
    }
    else if((compare(entry, p->word) != 0 && p->next != NULL)){
        printf("in second else case in addEntry");
        p = p->next;
        addEntry(p, entry);
      }
    else if(p->word == NULL){
      insert(p->word, entry);
      p->count = p->count + 1;
      p->next = temp;
    }
    else if((compare(entry, p->word) != 0 && p->next == NULL)){
      p->next = temp;
      insert(p->word, entry);
      p->count = p->count + 1;
      p->next = NULL;

    }
  }
  return head;
}*/

void printList(list head){
  list traversal = head;
  while(traversal->next != NULL){
    printf("%s", traversal->word);
    traversal = traversal->next;
  }
}

void insert(char* dest, char* toAdd){
  strcpy(dest, toAdd);
}

int compare(char* str1, char* str2){
  int value = strcmp(str1, str2);
  return value;
}

/* I wrote this function to collect words to use */
int getNextWord(char* output){
  int c;
  int i = 0;
  while((c = getchar()) != EOF){
    if (c == ' ' || c == '\n' || c == ',')
      break;
    else{
      output[i++] = c;
    }
  }
  output[i] = '\0';
  return i;
}

1 个答案:

答案 0 :(得分:1)

问题1:

当你创建一个新的struct LinkedList时(即在函数createNode中)你只得到一个成员word的char指针,它是未初始化的(即没有指向有效的内存)

但是你这样做:

insert(head-&gt; word,entry);

这实际上是head->word的字符串副本。因此,您使用未初始化的指针作为目标。这是未定义的行为。

在复制到malloc之前,您需要word一些内存(如果可用,请使用strdup。)

问题2:

void addEntry(list head, char* entry)

您将head作为指针值传递。在函数内部,您可以更改head。但是,您在函数内对head所做的任何更改都会丢失&#34;当函数返回时。换句话说,调用函数中的head更改。那(很可能)不是你想要的。

我想你想要:

void addEntry(list* head, char* entry)

当你这样做时,你需要在函数内以不同的方式使用head,即*head。例如:

  if(*head == NULL){
    *head = temp;
    insert((*head)->word, entry);
    printf("head->word = %s", (*head)->word);
    // p->next->word = NULL;   REMOVE THIS LINE
    return;
  }

以及main

中的来电
addEntry(&head, line);
BTW:typedef&#39; list是一个指针通常被认为是个坏主意。如果你真的想要键入一个指针,至少给它一个名字,告诉它是指针。喜欢:typedef struct LinkedList *pLinkedList;

问题3:

您永远不会初始化count。所以这里

p->count = p->count + 1;

您使用未初始化的变量。再次未定义的行为。

问题4:

看看这段代码:

  list temp, p;           // p is uninitialized
  temp = createNode();
  if(head == NULL){
    head = temp;
    insert(head->word, entry);
    printf("head->word = %s", head->word);
    p->next->word = NULL;   // Here p is used but it still uninitialized !!
    return;
  }

这又是未定义的行为