这个C代码中有内存泄漏吗?
在 C实现在递归函数中调用malloc。那不是内存泄漏吗这个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]
#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中的编程”之外,还有一个漏洞,因为没有匹配的调用<代码>免费< /代码>。这是最重要的部分。如果调用方没有正确处理返回的指针,则是另一个问题。