此C代码是否存在内存泄漏?

时间:2018-08-23 11:48:48

标签: c memory-leaks

https://en.wikibooks.org/wiki/Algorithm_Implementation/Mathematics/Extended_Euclidean_algorithm

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

如何释放在递归函数中分配的内存?

2 个答案:

答案 0 :(得分:3)

  

那不是内存泄漏吗?

是的。每次进行递归调用时,即在这里:

dxy = extendedEuclid(b, mod(a, b));

由于malloc被新值(也就是返回值)覆盖,因此刚刚dxy的内存泄漏了

代码应更像:

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仅执行一次,即没有递归调用时

答案 1 :(得分: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)

删除声明dxymalloc调用的行,将extendedEuclid(b, mod(a, b))更改为extendedEuclid(b, mod(a, b), dxy)并删除return语句。然后,主要是这样做:

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);

哦,还有don't cast malloc