Word translator program based on string comparison - heap memory assertion fails

75 views Asked by At

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;
}
1

There are 1 answers

0
Sourav Ghosh On BEST ANSWER

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.