这个C代码中有内存泄漏吗?

这个C代码中有内存泄漏吗?,c,memory-leaks,C,Memory Leaks,在 C实现在递归函数中调用malloc。那不是内存泄漏吗 #include <stdio.h> #include <stdlib.h> int mod (int a, int b){ return a %b; } int *extendedEuclid (int a, int b){ int *dxy = (int *)malloc(sizeof(int) *3); if (b ==0){ dxy[0] =a; dxy[1]

C实现在递归函数中调用malloc。那不是内存泄漏吗

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

int mod (int a, int b){
    return a %b; 
}   

int *extendedEuclid (int a, int b){
   int *dxy = (int *)malloc(sizeof(int) *3);

   if (b ==0){
      dxy[0] =a; dxy[1] =1; dxy[2] =0;

       return dxy;
   }
   else{
       int t, t2;
       dxy = extendedEuclid(b, mod(a, b));
       t =dxy[1];
       t2 =dxy[2];
       dxy[1] =dxy[2];
       dxy[2] = t - a/b *t2;

       return dxy;
    }
}

int main(void)
{
   int a =99, b =78;
   int *ptr;

   ptr =extendedEuclid (a, b);
   printf("%d = %d * %d + %d * %d \n",ptr[0], a, ptr[1], b, ptr[2] );

   return 0;        
}
#包括
#包括
内部模式(内部a、内部b){
返回%b;
}   
int*扩展欧几里得(int a,int b){
int*dxy=(int*)malloc(sizeof(int)*3);
如果(b==0){
dxy[0]=a;dxy[1]=1;dxy[2]=0;
返回dxy;
}
否则{
int t,t2;
dxy=扩展欧几里得(b,mod(a,b));
t=dxy[1];
t2=dxy[2];
dxy[1]=dxy[2];
dxy[2]=t-a/b*t2;
返回dxy;
}
}
内部主(空)
{
INTA=99,b=78;
int*ptr;
ptr=扩展欧几里得(a,b);
printf(“%d=%d*%d+%d*%d\n”,ptr[0],a,ptr[1],b,ptr[2]);
返回0;
}
如何释放递归函数中分配的内存

那不是内存泄漏吗

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

int mod (int a, int b){
    return a %b; 
}   

int *extendedEuclid (int a, int b){
   int *dxy = (int *)malloc(sizeof(int) *3);

   if (b ==0){
      dxy[0] =a; dxy[1] =1; dxy[2] =0;

       return dxy;
   }
   else{
       int t, t2;
       dxy = extendedEuclid(b, mod(a, b));
       t =dxy[1];
       t2 =dxy[2];
       dxy[1] =dxy[2];
       dxy[2] = t - a/b *t2;

       return dxy;
    }
}

int main(void)
{
   int a =99, b =78;
   int *ptr;

   ptr =extendedEuclid (a, b);
   printf("%d = %d * %d + %d * %d \n",ptr[0], a, ptr[1], b, ptr[2] );

   return 0;        
}
是的。每次进行递归调用时,即:

dxy = extendedEuclid(b, mod(a, b));
dxy
被一个新值(也称为返回值)覆盖时,刚刚
malloc
的内存泄漏

代码应该更像:

int *extendedEuclid (int a, int b){
    int *dxy;
    if (b ==0){
        dxy = (int *)malloc(sizeof(int) *3);  // Move malloc to here
        dxy[0] =a; dxy[1] =1; dxy[2] =0;

        return dxy;
    }
    else { ....
因此,
malloc
只执行一次,即当没有递归调用时

那不是内存泄漏吗

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

int mod (int a, int b){
    return a %b; 
}   

int *extendedEuclid (int a, int b){
   int *dxy = (int *)malloc(sizeof(int) *3);

   if (b ==0){
      dxy[0] =a; dxy[1] =1; dxy[2] =0;

       return dxy;
   }
   else{
       int t, t2;
       dxy = extendedEuclid(b, mod(a, b));
       t =dxy[1];
       t2 =dxy[2];
       dxy[1] =dxy[2];
       dxy[2] = t - a/b *t2;

       return dxy;
    }
}

int main(void)
{
   int a =99, b =78;
   int *ptr;

   ptr =extendedEuclid (a, b);
   printf("%d = %d * %d + %d * %d \n",ptr[0], a, ptr[1], b, ptr[2] );

   return 0;        
}
是的。查看这一点的一个简单方法是程序
valgrind

$ valgrind ./a.out 
==8528== Memcheck, a memory error detector
==8528== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==8528== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==8528== Command: ./a.out
==8528== 
3 = 99 * -11 + 78 * 14 
==8528== 
==8528== HEAP SUMMARY:
==8528==     in use at exit: 72 bytes in 6 blocks
==8528==   total heap usage: 7 allocs, 1 frees, 1,096 bytes allocated
==8528== 
==8528== LEAK SUMMARY:
==8528==    definitely lost: 72 bytes in 6 blocks
==8528==    indirectly lost: 0 bytes in 0 blocks
==8528==      possibly lost: 0 bytes in 0 blocks
==8528==    still reachable: 0 bytes in 0 blocks
==8528==         suppressed: 0 bytes in 0 blocks
==8528== Rerun with --leak-check=full to see details of leaked memory
==8528== 
==8528== For counts of detected and suppressed errors, rerun with: -v
==8528== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
如何释放递归函数中分配的内存

很难对那个问题给出一般性的答案。这取决于具体的功能。在这种特定情况下,您可以更改它,以便将结果写入输出参数,而不是返回指针。然后,您的方法的原型可以如下所示:

void extendedEuclid (int a, int b, int *dxy)
删除声明
dxy
的行和
malloc
调用,将
extendededuclid(b,mod(a,b))
更改为
extendededuclid(b,mod(a,b),dxy)
并删除返回语句。然后,主要是这样做:

int *ptr = malloc(sizeof(int) *3);
extendedEuclid (a, b, ptr);
printf("%d = %d * %d + %d * %d \n",ptr[0], a, ptr[1], b, ptr[2] );
free(ptr);

哦,严格来说,如果每个
malloc
都没有
free
,那么总是有内存泄漏。是的,这是一个泄漏。特别是在
else
部分(进行递归调用),分配的内存被完全忽略。如果这本书的其余部分包含如此糟糕的代码,那么我建议您尝试寻找另一本书。问题不在于分配内存,问题在于分配的内存束在不需要时没有被释放。无论如何,你可以用valgrind之类的工具自己检查一下。这个实现似乎是为了演示算法,而不是为了提高产品质量。即使在递归的每个步骤中没有错误的分配,它也不会尝试释放内存。它似乎依赖于在托管环境中执行,在托管环境中,程序终止时所有内存都将由托管平台回收。@Someprogrammerdude-这不是对此类代码的认可。这是一个可能的解释,除了“谁写了这篇文章不知道C中的编程”之外,还有一个漏洞,因为没有匹配的调用<代码>免费< /代码>。这是最重要的部分。如果调用方没有正确处理返回的指针,则是另一个问题。