在C中访问结构成员时获取seg错误
我试图实现一个用C存储单词的trie,但在尝试访问结构成员时遇到了一个分段错误 代码如下:在C中访问结构成员时获取seg错误,c,struct,segmentation-fault,C,Struct,Segmentation Fault,我试图实现一个用C存储单词的trie,但在尝试访问结构成员时遇到了一个分段错误 代码如下: #include <stdbool.h> #include <ctype.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #define ALPHABET_SIZE 27 #define SIZE 45 //Trie data structure declaratio
#include <stdbool.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define ALPHABET_SIZE 27
#define SIZE 45
//Trie data structure declaration
typedef struct _dictionary {
bool is_word;
char letter;
struct _dictionary *children[ALPHABET_SIZE];
} dicto;
dicto *DICT;
//Function prototypes
void insert(char *string);
int toIndex(char s);
int main() {
FILE *fp = fopen("small", "r");
if (fp == NULL) {
printf("Could not open file\n");
return 1;
}
char word[46];
while (fgets(word, sizeof(word), fp)) {
insert(word);
if (feof(fp)) {
return 0;
}
}
return 2;
}
//Inserts word into trie
void insert(char *string) {
dicto *trav; //Pointer to walk through the trie
trav = DICT;
for (int n = 0; n = strlen(string); n++) {
if (trav->children[toIndex(string[n])] == NULL) {
trav->children[toIndex(string[n])] = malloc(sizeof(DICT));
trav->letter = string[n];
trav = trav->children[toIndex(string[n])];
} else {
trav->letter = string[n];
trav = trav->children[toIndex(string[n])];
}
if (trav->letter == '\0') {
trav->is_word = true;
}
}
return;
}
/**
* Output alphabetic index from given input
*/
int toIndex(char s) {
s = toupper(s);
int index = s - 65;
return index;
}
通过运行GDB,错误似乎来自第54行:
if (trav->children[toIndex(string[n])] == NULL)
不知道会发生什么。这只是对问题中代码可能出现的问题之一的快速回答。我没有通读整件事 执行以下分配后,内存中充满了垃圾数据:
trav->children[toIndex(string[n])] = malloc(sizeof(dicto));
您最好使用calloc(这保证了内存归零):
或者自己将数据归零:
trav->children[toIndex(string[n])] = malloc(sizeof(dicto));
memset(trav->children[toIndex(string[n])], 0, sizeof(dicto));
如果将垃圾数据保留在内存中,则以下条件可能为false,即使它应该为true:
if(trav->children[toIndex(string[n])] == NULL)
附言
另外,
sizeof(DICT)
是指针的大小,而不是结构的大小。你可以考虑<代码> siZeof(*DICT)< /C>或<代码> siZeof(DITO)< /> > < P>代码中存在多个问题:
- 测试
并没有按照您的想法进行,它实际上是不必要的,因为feof(fp)
将在文件末尾返回fgets()
NULL
- (int n=0;n=strlen(string);n++)的循环
永远不会结束,因为
在每次迭代时被重新计算为字符串的长度,请改用此循环:n
for (int n = 0, len = strlen(string); n < len; n++) {
是trav
(DICT
)。它是dicto*DICT;
。也NULL
-->for(int n=0;n=strlen(string);n++)
或for(int n=0;n
for(int n=0;string[n];n++)
if(trav->children[toIndex(string[n])] == NULL)
for (int n = 0, len = strlen(string); n < len; n++) {
#include <stdbool.h> #include <ctype.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #define ALPHABET_SIZE 27 #define SIZE 45 //Trie data structure declaration typedef struct _dictionary { bool is_word; char letter; struct _dictionary *children[ALPHABET_SIZE]; } dicto; dicto *DICT; //Function prototypes void insert(char *string); int toIndex(char s); int main(void) { char word[SIZE + 1]; FILE *fp = fopen("small", "r"); if (fp == NULL) { printf("Could not open file\n"); return 1; } while (fgets(word, sizeof(word), fp)) { insert(word); } return 0; } //Inserts word into trie void insert(char *string) { dicto *trav = DICT; //Pointer to walk through the trie for (int n = 0, len = strlen(string); n < len; n++) { int index = toIndex(string[n]); if (trav->children[index] == NULL) { trav->children[index] = malloc(sizeof(DICT)); } trav->letter = string[n]; trav = trav->children[index]; } trav->is_word = true; } /** * Output alphabetic index from given input (assuming ASCII) */ int toIndex(char c) { if (c >= 'a' && c <= 'z') return c - 'a'; if (c >= 'A' && c <= 'Z') return c - 'A'; return 26; /* not a letter */ }