繁体   English   中英

调用 malloc() 后 Free() 无法按预期工作

[英]Free() doesn't work as expected after calling malloc()

我用 C 编写了以下函数,但有两个问题:

  1. 我被要求释放动态分配的内存以防止使用过多的 RAM,但free(word)只会导致我的程序出现错误。 如果我删除它一切正常,为什么会发生这种情况? 我按照许多不同文章中的建议使用完word后免费使用。

  2. 我被要求使用具有最小所需空间的 malloc,但我该怎么做? 目前我的代码分配max_str_len的RAM块,但如果字要短得多像a字母,我不希望分配200块了点。 请问有什么建议吗?

int read_words(char *words[], int size, int max_str_len) {
    char *word;
    char ch;
    int i;
    for (i = 0; i < size; ++i) {
        word = (char *)malloc((max_str_len + 1) * sizeof(char));
        if (word == NULL)
            return -1;
        for (int j = 0; j < max_str_len; ++j) {
            scanf("%c", &ch);
            if (ch == '\n') break;
            if (ch == EOF || ch == 'R') return i;
            word[j] = ch;
        }
        words[i] = word;
        free(word);
    }
    return i;
}

您将malloc 'd char*放入调用者提供的words[i] ,然后释放它。 那没有意义。 如果你释放它,调用者就不能对它做任何事情。

如果你想要malloc 'd串是最小的,你可以realloc他们或者你可以读入一个大的缓冲区(在函数的开始也许分配),然后将结果复制到malloc倒是缓冲区的大小恰到好处。

请注意,您也未能检查scanf是否存在错误,并且如果您在函数中间出现内存故障,则会导致内存泄漏——通过返回 -1,您实际上会丢失有关已填充words元素数量的信息拥有指针。 您可能希望返回该信息( return i; )或在malloc失败之前释放该函数分配的所有指针。

您的代码中有多个问题:

  • 您释放了为每个字分配的内存,但您返回指向调用者提供的数组中已释放块的指针,当调用者取消引用这些指针时会导致未定义的行为。
  • 您对文件结尾的测试不正确:然后scanf()将返回EOF ,但该字符不会被设置为EOF ,这可能不适合char 您应该使用getchar()并使ch成为int
  • 您应该在读取的字符串末尾设置一个空终止符。
  • 一旦知道字符串长度,就可以使用realloc来缩小内存块。

这是一个修改后的版本:

int read_words(char *words[], int size, int max_str_len) {
    char *word, *p;
    int i, j, ch;
    for (i = 0; i < size;) {
        word = (char *)malloc(max_str_len + 1);
        if (word == NULL) {
            /* free the words allocated so far and return a failure code */
            while (i-- > 0)
                free(words[i];
            return -1;
        }
        for (j = 0; j < max_str_len; ++j) {
            ch = getchar();
            if (ch == '\n' || ch == EOF || ch == 'R') break;
            word[j] = ch;
        }
        if (j == 0 && (ch == EOF || ch == 'R'))
            break;
        word[j] = '\0';
        p = (char *)realloc(word, j + 1);
        if (p != NULL)
            word = p;
        words[i++] = word;
        if (ch == EOF || ch == 'R')
            break;
    }
    return i;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM