Goal:
- Make global array of string (dictionary) given that size can be computed only in function
load(). - Print dictionary on the screen with function
print().
My approach:
Create global pointer to string, create array of strings in load() and assign local array to global pointer.
Problem:
If I try to print global array (and local as well) inside load(), everything's fine, but in case of printing with print(), segfault occurs somewhere in the end of array. GDB and valgrind outputs seem cryptic to me. I give up. What's wrong?
Source and dictionary are here.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
// length of the longest word in dictionary
#define LENGTH 45
// dictionary file
#define DICTIONARY "large"
// prototypes
void load(const char* dictionary);
void print(void);
// global dictionary size
int dict_size = 0;
// global dictionary
char **global_dict;
int main(void)
{
load(DICTIONARY);
print();
return 0;
}
/**
* Loads dictionary into memory.
*/
void load(const char* dictionary)
{
// open dictionary file
FILE *dict_file = fopen(dictionary, "r");
// compute size of dictionary
for (int c = fgetc(dict_file); c != EOF; c = fgetc(dict_file))
{
// look for '\n' (one '\n' means one word)
if (c == '\n')
{
dict_size++;
}
}
// return to beginning of file
fseek(dict_file, 0, SEEK_SET);
// local array
char *dict[dict_size];
// variables for reading
int word_length = 0;
int dict_index = 0;
char word[LENGTH + 1];
// iteration over characters
for (int c = fgetc(dict_file); c != EOF; c = fgetc(dict_file))
{
// allow only letters
if (c != '\n')
{
// append character to word
word[word_length] = c;
word_length++;
}
// if c = \n and some letters're already in the word
else if (word_length > 0)
{
// terminate current word
word[word_length] = '\0';
//write word to local dictionary
dict[dict_index] = malloc(word_length + 1);
strcpy(dict[dict_index], word);
dict_index++;
// prepare for next word
word_length = 0;
}
}
// make local dictioinary global
global_dict = dict;
}
/**
* Prints dictionary.
*/
void print(void)
{
for (int i = 0; i < dict_size; i++)
printf("%s %p\n", global_dict[i], global_dict[i]);
}