【问题标题】:Word translator program based on string comparison - heap memory assertion fails基于字符串比较的字翻译程序——堆内存断言失败
【发布时间】:2015-09-02 06:33:02
【问题描述】:

我制作了一个程序,从文件english_dictionary.txt 中读取英语中最常用的 200 个单词,并在foreign_dictionary.txt 中将各个单词的翻译放入外语中。

.txt 文件的内容放在两个char * 类型的200 元素数组中。

然后程序从文件text_to_translate.txt 中读取包含英文文本的文件,如果找到匹配项(这发生在compute_text 函数内部),它将用外文替换英文字符串(单词)。但它不起作用,我对堆内存的断言失败,所以我想我在 malloc 或类似的东西上出错了,但我不明白我错在哪里。

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

【问题讨论】:

  • 下次查看valgrind 是否有任何可能与内存分配有关的问题。
  • @Jongware KILLER APP,谢谢! windows也有类似的东西吗?
  • 抱歉,我不知道它仅适用于 Mac/Linux:“Windows 不在考虑范围内,因为移植到它需要进行如此多的更改,这几乎是一个单独的项目”(valgrind/platforms)。但请参阅 Is there a good Valgrind substitute for Windows? 以获取建议列表。

标签: c arrays string malloc dynamic-memory-allocation


【解决方案1】:

在您的代码中,tok 没有指向动态分配的内存。你不需要(也不能)free() 它。删除

 free(tok);

来自代码。

来自man page of free()

free(ptr) 函数释放由ptr 指向的内存空间,该内存空间必须由先前对malloc()calloc()realloc() 的调用返回。否则,或者如果之前已经调用过free(ptr),则undefined behaviour。 发生。

也就是说,在使用返回的指针之前,请始终检查 fopen()malloc()(可能还有所有库函数)的返回值,以确保成功。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-04
    • 2018-09-06
    • 2016-07-05
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多