为什么我的程序有内存泄漏?

时间:2017-03-26 05:38:23

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

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

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

在我的程序中,我首先为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';
}

2 个答案:

答案 0 :(得分:3)

我在这里看到的问题是

   free(oldWord);

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

那说了一些注意事项

  • 类似

    的语法
    word = realloc(word, i + 1);
    

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

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

答案 1 :(得分:0)

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

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

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

  • 分配0大小的块具有未指定的行为:它可能返回NULL或有效指针,该指针不应被解除引用但可以传递给free()realloc()。< / p>

  • 您不测试文件结尾:如果文件中没有空格或换行符,则存在无限循环,例如文件为空。

  • 在调用之前,您没有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;
}