【问题标题】:Why Does my program have Memory Leaks?为什么我的程序有内存泄漏?
【发布时间】:2017-03-26 05:38:23
【问题描述】:

我正在尝试创建一个小的 c 程序,它将读取任意大小的字符串,而不会出现任何内存泄漏。

根据我的研究,函数 ma​​lloc 可用于为我们想要存储的任何数据分配多个字节。

在我的程序中,我首先为 0 个字符分配空间,然后让指针 word 指向它。然后,每当我读取单个字符时,我都会创建一个指向 word 的指针 oldWord,一旦我为新字符分配了更大的内存位置,它就会释放旧的内存位置。

我的研究表明,函数 free 可用于释放不再需要的旧内存位置。但是,我不确定我哪里出错了。下面你可以看到我的代码。

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

int main(void){
    char *word = malloc(0);

    printf("Enter name: ");
    readWord(word);
    printf("Your name is: %s\n", word);

    free(word);

    word = realloc(0);

    printf("Enter name: ");
    readWord(word);
    printf("Your name is: %s\n", word);

    free(word);

    return 0;
}

void readWord(char *word){
    int i = 0;
    char *oldWord, c = getchar();

    while(c != ' ' && c != '\n'){
        oldWord = word;
        word = realloc(word, i + 1);
        free(oldWord);
        word[i++] = c;
        c = getchar();
    }

    oldWord = word;
    word = realloc(word, i + 1);
    free(oldWord);
    word[i] = '\0';
}

【问题讨论】:

标签: c pointers memory-leaks malloc dynamic-memory-allocation


【解决方案1】:

我在这里看到的问题在于

   free(oldWord);

不检查realloc()失败。如果realloc() 成功,则将相同的指针传递给free() 会导致undefined behavior

也就是说,还有一些注意事项

  • 类似的语法

    word = realloc(word, i + 1);
    

    很危险,如果realloc() 失败,您也会丢失实际的指针。您应该使用一个临时指针来保存realloc() 的返回值,检查是否成功,然后再将其分配回原始指针(如果需要)。

  • 在您的代码中,c 属于 char 类型,它可能不足以容纳 getchar() 返回的所有可能值,例如 EOF。您应该使用int 类型,这就是getchar() 返回的内容。

【讨论】:

    【解决方案2】:

    您的代码中存在多个问题:

    • free 是你传递给 realloc() 的指针。这是不正确的,因为如果块被移动,realloc() 已经释放了内存。 否则指针被释放两次。

    • readWord() 重新分配的指针永远不会传回给调用者。

    • 分配大小为 0 的块具有未指定的行为:它可能返回 NULL 或不应取消引用但可以传递给 free()realloc() 的有效指针。

    • 您不测试文件是否结束:如果文件中没有空格或换行符(例如文件为空),则会出现无限循环。

    • 在调用 readWord() 之前,您没有原型。

    这是一个改进但简单的版本:

    #include <ctype.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    char *readWord(void);
    
    int main(void) {
        char *word;
    
        printf("Enter name: ");
        word = readWord();
        if (word == NULL) {
            printf("Unexpected end of file\n");
        else
            printf("Your name is: %s\n", word);
    
        free(word);
        return 0;
    }
    
    char *readWord(void) {
        int c;
        size_t i = 0;
        char *word = NULL;
    
        while ((c = getchar()) != EOF && !isspace(c)) {
            word = realloc(word, i + 2);
            if (word == NULL)
                break;
            word[i++] = c;
            word[i] = '\0';
        }
        return word;
    }
    

    【讨论】:

    • malloc(0) 未指定是否为空指针(非实现定义)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-17
    • 2011-12-25
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    • 1970-01-01
    相关资源
    最近更新 更多