0

I made a program that reads from file english_dictionary.txt the 200 most frequently used words in the English language, and in foreign_dictionary.txt I put the translations of the respective words in a foreign language.

The content of the .txt files is placed in two char * type array of 200 elements.

Then the program reads from file text_to_translate.txt, that containing a text in English, and would replace the strings(words) in English with foreign ones if it finds a match (this happens inside the compute_text function). But it does not work, i've the failure of assertion about heap memory, so i suppose i've wrong something with malloc or something like that, but i can't understand where i wrong.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

void foreign_dictionary(char **foreign, FILE *fp){

    char *buffer = malloc(30 * sizeof(char));
    char *tok;
    int i;

    for (i = 0; i < 200; ++i){
        fgets(buffer, 29, fp);
        tok = strtok(buffer, "\n");
        foreign[i] = malloc(strlen(tok) + 1);
        strcpy(foreign[i], tok);
    }

    free(tok);
    free(buffer);
}

void dictionary(char **english, FILE *fp){

    int i;
    char *tok;

    char *buffer = malloc(30 * sizeof(char));

    for (i = 0; i < 200; ++i){
        fgets(buffer, 29, fp);
        tok = strtok(buffer, " \n");
        english[i] = malloc(strlen(tok) + 1);
        strcpy(english[i], tok);
    }
    free(buffer);
    free(tok);
}

void compute_text(char **text,FILE *fp){

    char *buffer;
    int i, j, flag = 0, words_number = 0, cnt_letters_word = 0;

    buffer = malloc(100 * sizeof(char));

    while (fgets(buffer, 100, fp) != NULL){
        for (i = 0; i < 100; ++i){
            if (buffer[i] == ' ' || buffer[i] == '\0'){
                text[words_number] = malloc((cnt_letters_word + 1)* sizeof(char));
                for (j = 0; j < cnt_letters_word; ++j){
                    if (isupper(buffer[flag + j]))
                        text[words_number][j] = tolower(buffer[flag + j]);
                    else
                        text[words_number][j] = buffer[flag + j];
                }
                text[words_number][cnt_letters_word] = '\0';
                flag = i + 1;
                cnt_letters_word = 0;
                ++words_number;
            }
            else if (buffer[i] == '\n' || buffer[i] == ',' || buffer[i] == '.' || buffer[i] == ';' || buffer[i] == ':')
                ;
            else
                ++cnt_letters_word;
        }
        flag = 0;
        cnt_letters_word = 0;
    }
    free(buffer);
}

int main(void){

    char *foreign[200], *english[200], *text[50];

    FILE *fp = fopen("foreign_dictionary.txt", "r");
    foreign_dictionary(foreign, fp);
    fclose(fp);
    fp = fopen("english_dictionary.txt", "r");
    dictionary(english, fp);
    fclose(fp);
    fp = fopen("text_to_translate.txt", "r");
    compute_text(text, fp);
    fclose(fp);

    return 0;
}
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
wing
  • 57
  • 1
  • 9
  • 1
    Next time look into [`valgrind`](http://valgrind.org/) for any problem possibly related to memory allocation. – Jongware Jun 17 '15 at 08:20
  • @Jongware KILLER APP, thanks! There is something similar for windows too? – wing Jun 17 '15 at 09:52
  • 1
    Sorry, I did not know it's for Mac/Linux only: "Windows is not under consideration because porting to it would require so many changes it would almost be a separate project" ([valgrind/platforms](http://valgrind.org/info/platforms.html)). But see [Is there a good Valgrind substitute for Windows?](http://stackoverflow.com/questions/413477/is-there-a-good-valgrind-substitute-for-windows) for a list of suggestions. – Jongware Jun 17 '15 at 10:12

1 Answers1

3

In your code, tok is not pointing to dynamically allocated memory. You need not (and can not) free() it. Remove

 free(tok);

from the code.

From the man page of free()

The free(ptr) function frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc() or realloc(). Otherwise, or if free(ptr) has already been called before, undefined behaviour. occurs.

That said, always check the return value of fopen() and malloc() (and possibly, all library functions) to ensure success before using the returned pointer.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261