Malloc在循环中导致内存泄漏

时间:2014-01-06 01:28:25

标签: c memory-leaks malloc

任何人都可以帮我解决这段简单的代码似乎导致内存泄漏,但我不知道为什么?

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

int* get_point()
{
    int* point = malloc(2*sizeof(int));
    point[0] = 5;
    point[1] = 8;

    return point;
}

int main(void)
{
    int* point;
    int counter;

    for(counter = 0; counter < 100; counter++) 
    {
        point = get_point();
    }

    free(point);
    return 0;
}

我知道我不是在循环中释放点,但我不是只是重新分配一个新的内存块?如何摆脱最后一次循环中的旧内存?

当你通过循环间接调用malloc时,有人会建议解决这个问题吗?我知道可能有更好的方法来修复此代码以执行相同的操作,但更正此提取更好,以便我可以看到导致问题的原因?

4 个答案:

答案 0 :(得分:4)

循环的每次迭代都会在堆上产生新的分配。但是你只需要释放一次这个分配的内存,最后分配。为确保代码不泄漏,您需要将自由放在循环内部:

像这样:

int main(void)
{
    int* point;
    int i;

    for(counter = 0; counter < 100; counter++) 
    {
        point = get_point();
        free(point); 
    }
    return 0;
}

这种方法的替代方法是在函数外部分配一次,然后循环,然后将分配的数据传递给函数。

答案 1 :(得分:1)

你分配了100次,但只免费一次。确定它有内存泄漏。

你需要释放所有带循环的动态内存。

答案 2 :(得分:1)

  

不是我只是将它重新分配给新的记忆块吗?

没有。每次拨打malloc()时,都会为point分配一个新的内存块,而前一个内存块将丢失。

通常,要将内存重新分配给现有指针,请使用realloc(),如下所示:

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

void get_point(int **p)
{
    *p = realloc(2*sizeof *p);
    if (*p)
    {
      (*p)[0] = 5;
      (*p)[1] = 8;
    }
}

int main(void)
{
    int *point = NULL;
    int i;

    for(counter = 0; counter < 100; counter++) 
    {
        get_point(&point);
    }

    free(point);
    return 0;
}

但是这段代码没什么意义,因为realloc()总是需要相同数量的内存。举个例子,你会选择更简单的东西:

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

int *get_point(void)
{
   int *p;
   p = malloc (2 * sizeof *p);
   if (p)
   {
     p[0] = 5;
     p[1] = 8;
   }
   return p;
}

int main(void)
{
    int *point = NULL;
    int i;

    for(counter = 0; counter < 100; counter++) 
    {
        point = get_point(point);
        if (point)
        {
          /* do stuff with point */
          free (point);
        }
    }
    return 0;
}

答案 3 :(得分:0)

在你的循环中,每次调用malloc()时,它会在内存中查找一个空闲空间并分配作为参数传递的大小,这意味着每次调用它时指针point指向一个新的内存中的空间和之前的空间丢失了,但该空间中的内存仍然保留,导致内存泄漏。

要解决此问题,您必须先调用free()函数释放内存空间,然后再指向新内存:

for(counter = 0; counter < 100; counter++) 
{
    point = get_point();
    free(point);
}

请注意,free函数不会更改point本身的值,因此它仍指向相同(现在无效)的位置。