简体   繁体   English

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

[英]Why Does my program have Memory Leaks?

I am trying to create a small c program that will read a string with arbitrary size, without having any memory leaks. 我正在尝试创建一个小的c程序 ,它将读取任意大小的字符串,而不会有任何内存泄漏。

According to my research, the function malloc can be used to allocate a number of bytes for whatever data we want to store. 根据我的研究,函数malloc可用于为我们想要存储的任何数据分配多个字节。

In my program, I start by allocating space for 0 characters, and I make the pointer word point to it. 在我的计划,我通过为0个字符分配空间开始,我使指针指向它。 Then whenever I read a single character, I make a pointer oldWord that points to word , which frees the old memory location once I allocate a larger memory location for the new character. 然后,每当我读到一个字符,我做一个指针oldWord指向的话 ,一旦我分配了新的角色更大的内存位置,其释放旧的内存位置。

My research shows that the function free can be used to free an old memory location that is no longer needed. 我的研究表明, free函数可用于释放不再需要的旧内存位置。 However, I am not sure where I am going wrong. 但是,我不确定我哪里出错了。 Below you can see my code. 您可以在下面看到我的代码。

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

The problem as I see it here is with 我在这里看到的问题是

   free(oldWord);

without checking the failure of realloc() . 没有检查realloc()失败 In case realloc() is success, passing the same pointer to free() causes undefined behavior . 如果realloc()成功,将相同的指针传递给free()会导致未定义的行为

That said, some more notes 那说,还有一些说明

  • a syntax like 像这样的语法

     word = realloc(word, i + 1); 

    is dangerous, in case realloc() fails, you'll lose the actual pointer, too. 是危险的,如果realloc()失败,你也会失去实际的指针。 You should use a temporary pointer to hold the return value of realloc() , check for success and only then, assign it back to the original pointer, if you need. 您应该使用临时指针来保存realloc()的返回值,检查是否成功,然后,如果需要,将其分配回原始指针。

  • In your code, c is of char type, which may not be sufficient to hold all the possible values returned by getchar() , for example, EOF. 在您的代码中, cchar类型,可能不足以保存getchar()返回的所有可能值,例如EOF。 You should use an int type, that is what getchar() returns. 您应该使用int类型,即getchar()返回的类型。

There are multiple problems in your code: 您的代码中存在多个问题:

  • you free the pointer you passed to realloc() . free传递给realloc()的指针。 This is incorrect as realloc() will have freed the memory already if the block was moved. 这是不正确的,因为如果移动块, realloc()将释放内存。 Otherwise the pointer is freed twice. 否则指针被释放两次。

  • The pointer reallocated bu readWord() is never passed back to the caller. 指针重新分配bu readWord()永远不会传递给调用者。

  • Allocating a 0 sized block has unspecified behavior: it may return NULL or a valid pointer that should not be dereferenced but can be passed to free() or realloc() . 分配0大小的块具有未指定的行为:它可能返回NULL或有效指针,该指针不应被解除引用但可以传递给free()realloc()

  • You do not test for end of file: there is an infinite loop if the file does not have a space nor a linefeed in it, for example if the file is empty. 您不测试文件结尾:如果文件中没有空格或换行符,则存在无限循环,例如,如果文件为空。

  • you do not have a prototype for readWord() before it is called. 你在调用之前没有readWord()的原型。

Here is an improved yet simplistic version: 这是一个改进而简单的版本:

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

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

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