导致内存泄漏的循环中的Malloc

导致内存泄漏的循环中的Malloc,c,memory-leaks,malloc,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 coun

有人能帮我处理这段简单的代码吗?它似乎导致了内存泄漏,但我不知道为什么

#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;
}
#包括
#包括
int*get_point()
{
int*point=malloc(2*sizeof(int));
点[0]=5;
点[1]=8;
返回点;
}
内部主(空)
{
整数*点;
整数计数器;
用于(计数器=0;计数器<100;计数器++)
{
点=获取点();
}
自由(点);
返回0;
}
我知道我并没有释放循环中的点,但我不是在重新分配一个新的内存块吗?如何清除上次循环中的旧内存


当您通过循环间接调用malloc时,是否有人能提出解决方案?我知道可能有更好的方法来修复此代码以执行相同的操作,但最好更正此摘录,这样我就可以看到导致问题的原因了?

循环的每次迭代都会在堆上产生新的分配。但是,您只能释放此分配的内存一次,即最终分配。为了确保代码不会泄漏,您需要将空闲代码放在循环内部:

像这样:

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

    for(counter = 0; counter < 100; counter++) 
    {
        point = get_point();
        free(point); 
    }
    return 0;
}
int main(无效)
{
整数*点;
int i;
用于(计数器=0;计数器<100;计数器++)
{
点=获取点();
自由(点);
}
返回0;
}

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

您分配了100次,但只有一次空闲。当然,它有内存泄漏

您需要使用循环释放所有动态内存

我不是在重新分配一块新的内存吗

否。每次调用
malloc()
,都会将一个新内存块分配给
,上一个内存块将丢失

通常,要将内存重新分配给现有指针,请使用
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;
}

每次
malloc()都在循环中
被调用时,它会在内存中查找可用空间并分配作为参数传递的大小,这意味着每次调用时,指针
都指向内存中的新空间,以前的空间丢失,但该空间中的内存仍保留着,从而导致内存泄漏

要解决此问题,必须在指向新的内存空间之前调用函数以释放内存空间:

for(counter = 0; counter < 100; counter++) 
{
    point = get_point();
    free(point);
}
for(计数器=0;计数器<100;计数器++)
{
点=获取点();
自由(点);
}

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

或者您可以在
get\u point()中设置
point
static
。当我释放点时,我不必再次调用int*点,因为我释放了它吗?@alan4cult“再次调用int*点”是什么意思?如果你说的是
int*点函数开头的行,然后是否,在调用
free()
后,您不再需要该行。这一点与分配/释放内存无关。谢谢丹尼斯。我不确定。我认为空闲(点)释放指向的内存,并从堆栈中删除“点”,就好像它从未被声明过一样。@alan4cult不,不要担心“从堆栈中删除”,堆栈会自行处理
free
只是删除指针指向的数据,即堆中的数据。因此,当我调用free(point)时,我不必重新声明point,即再次调用int*point。如果我释放了point,编译器如何知道它仍然是指向int的指针类型?@alan4curt当你调用free时,你只释放
指向的内存空间,但指针
仍然存在。查看此参考资料谢谢,我想我明白了。因此,实际指针(int*point)在超出作用域之前不会被“删除”,但它所指向的内存可以被释放。很抱歉,将我的指针称为“point”,可能需要一个更好的名称。我在二维平面上用点表示(x,y)。
for(counter = 0; counter < 100; counter++) 
{
    point = get_point();
    free(point);
}