简体   繁体   中英

Segmentation fault, initializing recursive struct in C

Okay, I put together a simplified example of the problem code:

#include "stdio.h"
#include "string.h"

struct Trie{
    //Holds sub-tries for letters a-z
    struct Trie *sub[26];
    //Is this a substring, or a complete word?
    int is_word;
};
typedef struct Trie Trie;

Trie dictionary;

int main(int argc, char *argv[]){
    //A list of words
    char *words[7] = {"the","of","and","to","a","in","that"};

    //Add the words to the Trie structure
    int i=0, wordlen;
    Trie *sub_dict;
    for (;i<7; i++){
        //Reset
        printf("NEW WORD\n");
        sub_dict = &dictionary;
        //Add a word to the dictionary
        int j=0, c;
        while (c = words[i][j], c != '\0'){
            printf("char = %c\n",c);
            //Initialize the sub-Trie
            if (sub_dict->sub[c-97] == NULL)
                sub_dict->sub[c-97] = (Trie*) malloc(sizeof(Trie*));
            //Set as new sub-trie
            sub_dict = sub_dict->sub[c-97];
            j++;
        }
        sub_dict->is_word = 1;
    }
}

Basically, I have a Trie data structure that holds the letters "a" through "z". I have a list of words that should get added inside the while loop. Unfortunately, I get a segmentation fault at different points in the loop (depending on when I run it).

I'm guessing the problem has something to do with the line
sub_dict->sub[c-97] = (Trie*) malloc(sizeof(Trie*));
but I'm new to C , so I have absolutely no clue what's going on.

sub_dict->sub[c-97] = (Trie*) malloc(sizeof(Trie*)); there is an error.

sizeof(Trie*) will be 4 in 32bit os, because Trie* is a pointer, and the size of a pointer in 32bit os is 4. you can do like this: sub_dict->sub[c-97] = (Trie*) malloc(sizeof(Trie));

You seem to presume that when you do

something = (Trie*) malloc(sizeof(Trie*));

then the contents of that structure is initialized to zeroes (eg every member will start as NULL). This is not the case with malloc() . You have to either use calloc , or use memset() to reset it after allocation.

In fact, I'd call memset even on your starting dictionary to be on the safe side. (Even though global and static variables are apparently initialized to zero , so this might not be necessary for your case.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM