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]);
}
 
     
     
    