C Segmentation Fault(核心转储)与链表
C Segmentation Fault (core dump) with linked lists
我正在使用我命名为 word_entry 的链表。 word_entry 的结构如下:
struct word_entry
{
char *unique_word ;
int word_count ;
struct word_entry *next;
struct word_entry *prev;
} ;
这就是我使用代码的方式:
struct word_entry *head = NULL;
struct word_entry *curr = NULL;
int read_file( char *file_name )
{
int initialized = 0;//was head initialized?
char ch;
FILE *file;
struct word_entry *we = malloc(sizeof(struct word_entry));
we->unique_word = malloc(sizeof(char));
we->prev = NULL;
we->next = NULL;
char *s1 = malloc(sizeof(char));
char *s2 = s1;
file = fopen(file_name, "r");//opens the file
if(!file){
return 0;//file not opened
}else{
while((ch = fgetc(file))!= EOF){
if(ch >= 'A' && ch <= 'z'){
*s2++ = ch;
continue;
}
if(strlen(s1)>0){
if(!initialized){
head = malloc(sizeof(struct word_entry));
curr = head;
initialized = 1;
}
*s2 = '[=11=]';
strcpy(we->unique_word,s1);
we->word_count = 1;
curr = we;
printf("%s\n", head->unique_word);
s1 = malloc(sizeof(char));
s2 = s1;
}
}
return 1;
}
return 0; //file not opened
}
我不清楚为什么我修改curr时curr = head不修改head。我想了解如何实现我的代码,以便每当我修改 curr 时它也会修改 head 中的信息。
在您的示例中,您使用带有 sizeof(char) 的 malloc 来分配一个 char 指针(我假设?)。
这是不必要的,你不需要分配一个char *,你需要初始化一个内存块,这个char指针也会指向。
你在这里做的是尝试将一块内存写入单个字节
strcpy(we->unique_word,s1);
unique_word 是指向分配的 1 字节大小的内存块的指针 - 您写的超出了分配的范围。
更正确的方法是:
we->unique_word = (char *)malloc(strlen(s1) + 1); // For the null terminator
if (!we->unique_word) { /* Handle error where memory was not allocated */ }
strcpy(we->unique_word,s1);
您为这些 char *
分配了内存-
we->unique_word = malloc(sizeof(char)); // sizeof(char) is 1
....
char *s1 = malloc(sizeof(char));
即使你读了一个字符,'[=12=]'
也没有 space,当你将它们传递给 strlen
、strcpy
或用 [=15= 打印它们时] 导致 未定义的行为 。
您需要分配更多内存。
注意 - 您在每次迭代中分配内存,但从来没有 free
任何这些。这会导致内存泄漏。
I am not sure why curr = head
does not modify the head when I modify curr
那是因为 curr
指向 head
。如果您执行 curr=we
,curr 将停止指向 head
并指向 we
。这不会改变 head
。
我正在使用我命名为 word_entry 的链表。 word_entry 的结构如下:
struct word_entry
{
char *unique_word ;
int word_count ;
struct word_entry *next;
struct word_entry *prev;
} ;
这就是我使用代码的方式:
struct word_entry *head = NULL;
struct word_entry *curr = NULL;
int read_file( char *file_name )
{
int initialized = 0;//was head initialized?
char ch;
FILE *file;
struct word_entry *we = malloc(sizeof(struct word_entry));
we->unique_word = malloc(sizeof(char));
we->prev = NULL;
we->next = NULL;
char *s1 = malloc(sizeof(char));
char *s2 = s1;
file = fopen(file_name, "r");//opens the file
if(!file){
return 0;//file not opened
}else{
while((ch = fgetc(file))!= EOF){
if(ch >= 'A' && ch <= 'z'){
*s2++ = ch;
continue;
}
if(strlen(s1)>0){
if(!initialized){
head = malloc(sizeof(struct word_entry));
curr = head;
initialized = 1;
}
*s2 = '[=11=]';
strcpy(we->unique_word,s1);
we->word_count = 1;
curr = we;
printf("%s\n", head->unique_word);
s1 = malloc(sizeof(char));
s2 = s1;
}
}
return 1;
}
return 0; //file not opened
}
我不清楚为什么我修改curr时curr = head不修改head。我想了解如何实现我的代码,以便每当我修改 curr 时它也会修改 head 中的信息。
在您的示例中,您使用带有 sizeof(char) 的 malloc 来分配一个 char 指针(我假设?)。
这是不必要的,你不需要分配一个char *,你需要初始化一个内存块,这个char指针也会指向。
你在这里做的是尝试将一块内存写入单个字节
strcpy(we->unique_word,s1);
unique_word 是指向分配的 1 字节大小的内存块的指针 - 您写的超出了分配的范围。
更正确的方法是:
we->unique_word = (char *)malloc(strlen(s1) + 1); // For the null terminator
if (!we->unique_word) { /* Handle error where memory was not allocated */ }
strcpy(we->unique_word,s1);
您为这些 char *
分配了内存-
we->unique_word = malloc(sizeof(char)); // sizeof(char) is 1
....
char *s1 = malloc(sizeof(char));
即使你读了一个字符,'[=12=]'
也没有 space,当你将它们传递给 strlen
、strcpy
或用 [=15= 打印它们时] 导致 未定义的行为 。
您需要分配更多内存。
注意 - 您在每次迭代中分配内存,但从来没有 free
任何这些。这会导致内存泄漏。
I am not sure why
curr = head
does not modify the head when I modifycurr
那是因为 curr
指向 head
。如果您执行 curr=we
,curr 将停止指向 head
并指向 we
。这不会改变 head
。