在C中访问结构成员时获取seg错误

在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

我试图实现一个用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 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 */
    }