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

int main(void) {
    int x;
    int *in, *begin;
    in = (int *)malloc(sizeof(int));
    begin = in;
    while ((x = getchar()) != EOF) {
        *in = x;
        in++;
        in = (int *)malloc(sizeof(int));
    }
    *in = EOF;
    while ((x = *begin) != EOF) {
        putchar(x);
        begin++;
    }
    free(in);
    return 0;
}

我有一个偷偷摸摸的怀疑,它确实如此。

使用这个程序,我试图使用指针将不确定大小的用户输入存储到内存中,而不是使用char string[255]; fgets(string, sizeof(string));等。

编辑:当我运行它时,该程序不会崩溃或任何事情,我只是觉得分配的内存没有被释放。

4

5 回答 5

2

是的,程序有内存泄漏。

int *in, *begin;
in = (int *)malloc(sizeof(int));  /* allocate space for 1 int, at location "X" */
begin = in;
while ((x = getchar()) != EOF) {
    *in = x; 
    in++;    /* "in" increments address (to location) "X+1" */
    in = (int *)malloc(sizeof(int)); /* address "X+1" is lost as malloc returns  
                                        a different memory location, *not*
                                        necessarily at "X+2". Access to 
                                        previous data other than pointed to by 
                                        "begin" is lost */
}

*in = '\0';  /* this makes probably more senese than assigining EOF here */

free()分配内存时需要有相应的调用。

另外,我认为输入的存储不正确。

in从来没有给一个连续的内存块来存储数据。取而代之的是,一个存储 an 大小的内存位置int被重复分配并分配给in,但我们并不真正知道该内存在哪里,因此所有这些分配都丢失了,因为只有一个指针in在跟踪它们。

换句话说,泄漏包括重复为 a 的大小分配内存int,将其分配给in,然后在下一次循环中丢失对该位置的任何引用。

变量begin最初指向输入的第一个项目,但随后由于其指针值在输出循环中重复递增 1 而陷入未知内存。

更好的方法是在开始时分配一个更大的连续缓冲区,然后在增加指针时使用它in,或者从较小的数量开始,然后realloc()根据需要监视内存使用和更多(但要节省更多开销几句记忆)。

此外,在第一个循环结束时,而不是分配EOFto in,放入空字符会更有意义。

最后,free(in)程序底部的调用只释放了一个内存位置,没有释放其他先前分配的内存。

这是一个有效的快速组合版本,我尝试对原始代码进行最小的更改保持您的代码结构完整(我相信您有理由首先使用两个循环以这种方式编写它)尽管这可能只需一个循环就可以更紧凑地编写。

请注意,我最初为 100 个字符分配空间,根据您的需要进行调整,或者最初分配更少,但随后根据需要跟踪内存消耗和realloc()更多内存(我认为这是您的最初意图,但只是没有完全正确地实现)。

int main(void) {
    int x;
    int *in, *begin;
    int *start_loc;
    in = (int *)malloc(sizeof(int) * 100); /* continious space */
    begin = in;
    start_loc = in; /* keep track of start location for final free() call */

    while ((x = getchar()) != EOF) {
        *in = x;
        in++;
    }
    *in = 0;  /* terminator for the input string/data */

    while (*begin != 0) {   /* simplified */
        putchar(*begin);
        begin++;
    }

    free(start_loc);  /* free allocated memory */
    return 0;
}

这可以在不使用新变量的情况下编写start_loc(例如通过重用in),但我选择这样编写它是为了强调跟踪内存分配开始的重要性以及正确释放分配的内存的能力,因此解决您的内存泄漏问题。

于 2012-06-17T00:34:45.097 回答
1

当然存在内存泄漏,因为每次调用都会在您的程序中malloc进行相应的调用。free

在您的程序malloc中多次调用但只有一次调用free.

于 2012-06-17T00:33:43.557 回答
1

列文的回答是正确的。你增加in这里的值:

in++;

...但随后您将其重新分配给此处任意的地址:

in = (int *)malloc(sizeof(int));

要实现您想要做的事情,您需要:

  • 一次性分配一大块连续内存,并在需要扩展时使用 realloc() (这是您要实现的目标),或者;
  • 使用链表在不连续的内存地址列表中导航(这是您实际设法编写的)。
于 2012-06-17T00:38:11.333 回答
1

是的,你有。Free将为一个整数释放内存。你必须打电话给你打过free的每一个malloc电话。

此外,要将字符存储在连续缓冲区中,您必须malloc在开始时使用一定量的内存,并realloc在您读取的字符变得超过最初分配的内存时使用。

也不要忘记\0在字符串末尾再分配一个字符。

完成后,您可以致电free(buffer)并... 成功!没有内存泄漏!

以及它的代码:

/* Start with an initial size */
int size = 128;
char *buffer = (char *)malloc(size + 1);
int i = 0;
while ((x = getchar()) != EOF) {
        buffer[i] = x;
        i++;
        if(i == size){
           /*Do realloc and increase size */
        }
}
buffer[i] = '\0';
/* Do what you want with buffer */
free(buffer);
于 2012-06-17T00:43:30.770 回答
0

使用malloc分配内存时,应确保指向内存的指针不为NULL,释放内存后,最好将指针设为NULL

于 2012-06-17T06:33:28.187 回答