我在网上找不到类似的问题,主要是因为我的问题更具体一点,可能是某种逻辑错误造成的。
我试图逐个阅读(已经完成)并创建一个链表(使用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;
}
答案 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;
}
这又是未定义的行为