这个C代码会泄漏内存吗?
这是我的代码:这个C代码会泄漏内存吗?,c,pointers,memory-management,memory-leaks,C,Pointers,Memory Management,Memory Leaks,这是我的代码: typedef struct { int x; int *t; }vector; vector fct (vector v){ vector w; int i; w.x=v.x; w.t=malloc(w.x *sizeof(int)); for (i=0; i<w.x; i++) w.t[i]=2*v.t[i]; return w; } int main (){ int i;
typedef struct {
int x;
int *t;
}vector;
vector fct (vector v){
vector w;
int i;
w.x=v.x;
w.t=malloc(w.x *sizeof(int));
for (i=0; i<w.x; i++)
w.t[i]=2*v.t[i];
return w;
}
int main (){
int i;
vector v;
v.x=2;
v.t=malloc(2*sizeof(int));
v.t[0]=1; v.t[1]=5;
v=fct(v);
for (i=0; i<2; i++)
printf("%d \t",v.t[i]);
puts("");
free(v.t);
return 0;
}
typedef结构{
int x;
int*t;
}载体;
向量fct(向量v){
向量w;
int i;
w、 x=v.x;
w、 t=malloc(w.x*sizeof(int));
对于(i=0;i确定。向量t分配两次,释放一次。整个体系结构看起来有问题。确定。向量t分配两次,释放一次。整个体系结构看起来有问题
v.t=malloc(2*sizeof(int));
在这里,您将分配的内存分配给v.t
v=fct(v);
然后在这里用从fct
返回的内容覆盖v
的所有字段。这将丢弃v.t
的旧值,导致内存泄漏
在main
末尾对free
的调用正在释放fct
内部分配的内存
您可以通过保存v.t
并在保存的指针上调用free
来修复此漏洞:
vector v;
int *vt_sav;
v.x=2;
v.t=malloc(2*sizeof(int));
vt_sav = v.t;
v.t[0]=1; v.t[1]=5;
v=fct(v);
free(vt_sav);
在这里,您将分配的内存分配给v.t
v=fct(v);
然后在这里用从fct
返回的内容覆盖v
的所有字段。这将丢弃v.t
的旧值,导致内存泄漏
在main
末尾对free
的调用正在释放fct
内部分配的内存
您可以通过保存v.t
并在保存的指针上调用free
来修复此漏洞:
vector v;
int *vt_sav;
v.x=2;
v.t=malloc(2*sizeof(int));
vt_sav = v.t;
v.t[0]=1; v.t[1]=5;
v=fct(v);
free(vt_sav);
是的,您正在泄漏内存。w.t永远不会释放。
还可以通过指针而不是值传递结构。返回向量也很昂贵
您的新程序可以如下所示:
#include <stdio.h>
typedef struct {
int x;
int *t;
}vector;
void fct (vector *v, vector * w){
int i;
w->x = v->x;
for (i=0; i<w->x; i++)
w->t[i]=2*v->t[i];
}
int main (){
int i;
vector v;
vector w;
v.x=2;
v.t = malloc(2*sizeof(int));
w.t = malloc(2*sizeof(int));
v.t[0]=1;
v.t[1]=5;
fct(&v,&w);
for (i=0; i<2; i++)
printf("%d \t",w.t[i]);
puts("");
free(v.t);
free(w.t);
return 0;
}
是的,您正在泄漏内存。w.t永远不会释放。
还可以通过指针而不是值传递结构。返回向量也很昂贵
您的新程序可以如下所示:
#include <stdio.h>
typedef struct {
int x;
int *t;
}vector;
void fct (vector *v, vector * w){
int i;
w->x = v->x;
for (i=0; i<w->x; i++)
w->t[i]=2*v->t[i];
}
int main (){
int i;
vector v;
vector w;
v.x=2;
v.t = malloc(2*sizeof(int));
w.t = malloc(2*sizeof(int));
v.t[0]=1;
v.t[1]=5;
fct(&v,&w);
for (i=0; i<2; i++)
printf("%d \t",w.t[i]);
puts("");
free(v.t);
free(w.t);
return 0;
}
我非常担心它是否会导致内存泄漏,以及如何修复它
确实如此。在main()
中,分配内存并指向v.t
;然后用fct()
返回值中的一个指针覆盖该指针。原始指针丢失,并且没有它的其他副本,因此指向的内存泄漏
哦,我知道如果我定义另一个向量,比如说w,那么w=fct(v),它会解决这个问题,但是我需要一个不同的方法,一个即使函数返回到原始向量也能工作的方法
随着每一个动态内存分配都有义务释放这个内存,你可以把这个内存与一个内存指针的一个副本联系起来,作为一种名义标签。将标记转移到指针的其他副本。但是,如果带有标记的副本超出范围或被其他值覆盖,则会将指向的内容泄漏到内存
考虑一下这如何适用于您的案例:
分配内存并将指针分配给v.t
。这最初是指向已分配内存的指针的唯一副本,因此释放该内存的义务与此相关
您将v
的副本(包括v.t
的副本)传递给函数fct()
。您有两种选择:释放的义务可以保留在v.t
的原始副本上,也可以转移到函数接收的副本上。这是fct()定义的固有特征
,并且应该随附文档--您不能逐个调用进行选择。由于fct()
没有释放指针,因此您隐式选择了释放以保留原始副本的义务
fct()
执行自己的分配并返回结果指针的一个副本;这是函数执行后唯一幸存下来的副本,因此释放的义务必须伴随着它
当原始v.t
有义务释放时,用不同的值覆盖原始v.t
会泄漏原始内存。仍然有义务释放v.t
的(新)值,但无法再访问旧的动态分配内存
现在您有了一个选项:是否将义务作为函数调用的一部分转移到free。假设您确实转移了它;在这种情况下,fct()
必须在它返回之前执行该free()
。但是,在这种情况下,main()
在调用fct()
后,无论是否用该函数的结果覆盖v
,都不得使用v.t
的原始值
因此,您有一个选择:fct()
负责释放v.t
(如果愿意,它可以传递给另一个函数,或者它可以通过返回值返回给调用方),或者fct()
不承担这一责任。它的调用者需要做出相应的行为。你不能两全其美
我非常担心它是否会导致内存泄漏,以及如何修复它
确实如此。在main()
中,分配内存并指向v.t
;然后用fct()
返回值中的一个指针覆盖该指针。原始指针丢失,并且没有它的其他副本,因此指向的内存泄漏
哦,我知道如果我定义另一个向量,比如说w,那么w=fct(v),它会解决这个问题,但是我需要一个不同的方法,一个即使函数返回到原始向量也能工作的方法
<每一个动态内存分配都有义务释放那个内存。你可以考虑把这个内存的指针与一个内存的指针相关联,作为一种名义标签。你可以自由地(名义上)将标签传输到指针的不同副本。