Я продолжаю получать segfault для моей функции загрузки.
bool load(const char *dictionary)
{
//create a trie data type
typedef struct node
{
bool is_word;
struct node *children[27]; //this is a pointer too!
}node;
//create a pointer to the root of the trie and never move this (use traversal *)
node *root = malloc(sizeof(node));
for(int i=0; i<27; i++)
{
//NULL point all indexes of root -> children
root -> children[i] = NULL;
}
FILE *dptr = fopen(dictionary, "r");
if(dptr == NULL)
{
printf("Could not open dictionary\n");
return false;
}
char *c = NULL;
//scan the file char by char until end and store it in c
while(fscanf(dptr,"%s",c) != EOF)
{
//in the beginning of every word, make a traversal pointer copy of root so we can always refer back to root
node *trav = root;
//repeat for every word
while ((*c) != '\0')
{
//convert char into array index
int alpha = (tolower(*c) - 97);
//if array element is pointing to NULL, i.e. it hasn't been open yet,
if(trav -> children[alpha] == NULL)
{
//then create a new node and point it with the previous pointer.
node *next_node = malloc(sizeof(node));
trav -> children[alpha] = next_node;
//quit if malloc returns null
if(next_node == NULL)
{
printf("Could not open dictionary");
return false;
}
}
else if (trav -> children[alpha] != NULL)
{
//if an already existing path, just go to it
trav = trav -> children[alpha];
}
}
//a word is loaded.
trav -> is_word = true;
}
//success
free(root);
return true;
}
Я проверил, правильно ли я указал новые указатели на NULL во время инициализации. У меня есть три типа узлов: корневой, обходной (для перемещения) и следующий_узел. (i.) Можно ли обнулить узлы перед их выделением? (ii.) Кроме того, как мне освободить «next_node», если этот узел инициализирован и распределен внутри оператора if? node *next_node = malloc(sizeof(node));
(iii.) Если я хочу установить узлы как глобальные переменные, какие из них должны быть глобальными? (iv.) И, наконец, где я могу установить глобальные переменные: внутри main файла Sppeler.c, вне его main или где-то еще? Вопросов много, поэтому вам не обязательно отвечать на все из них, но было бы неплохо, если бы вы ответили на те, на которые уже есть ответы! Пожалуйста, укажите любые другие особенности в моем коде. Должно быть много. Я приму большинство ответов.
int alpha = (tolower(*c) - 97); if(trav -> children[alpha] == NULL)
это не то, что вы можете сделать, вы должны знать, действителен ли ваш ввод, поэтому вы должны проверить, является лиalpha
>= 0
и< 27
, прежде чем вы сможете продолжить и использовать его в качестве индекса вtrav -> children[alpha]
- person nos   schedule 05.09.2017char *c = NULL;
Вы никогда не выделяли память дляc
, поэтому fscanf дает сбой при записи в нее. - person Matt   schedule 05.09.2017fscanf
нужен указатель на место для хранения входящих данных. Вы установилиc
вNULL
и передали этоfscanf
, поэтому, когда вы читаете строку, она пытается писать через нулевой указатель. Создайте строковый буфер, скажем, из 256 символов и передайте его в качестве аргументаfscanf
. - person aghast   schedule 05.09.2017calloc
. Еще лучше написать отдельную функцию для выделения, инициализации и возврата указателя узла. - person aghast   schedule 05.09.2017