【发布时间】:2019-01-07 09:16:36
【问题描述】:
下面的代码显示了一个重复分配内存而不首先调用free 的示例。相反,它在循环之后释放**sign。
#include <stdio.h>
#include <stdlib.h>
float ** fun(int nloc)
{
float **sign;
int i,nt=100,it,k;
sign=(float **)calloc(nloc,sizeof(float *));
for (i=0;i<nloc;i++)
sign[i] = (float *)calloc(nt,sizeof(float *));
for (it=0;it<nt;it++){
for (k=0;k<nloc;k++){
sign[k][it]=it*0.2;
}
}
return sign;
}
int main(int argc, char *argv[])
{
int i,isrc,n=3,nloc=1;
float **sign=NULL;
for (isrc=0;isrc<n;isrc++){
sign = fun(nloc);
}
for (i=0;i<nloc;i++){
free(sign[i]);
}
free(sign);
exit(0);
}
这是一个正确的代码 sn-p。我的问题是:为什么我们可以在每次迭代中为指针分配内存而不必先释放它是合法的?
[补充信息]:
大家好,我认为有一种情况我们不能在循环中使用free 内存。如果buffer=p 和p 在循环外定义,比如:
float *buffer, *p;
/* Elements of p calculated */
for (...){
/* allocate memory for **buffer */
buffer = p;
free(buffer)
/* if free here will cause p lost */
}
如果在每个循环结束时释放buffer,可能会导致p丢失,因为buffer和p共享相同的内存地址。
【问题讨论】:
-
你明白
sign和sign[0], sign[1], etc.的区别吗? -
他们不是nloc不同的指针吗?
-
代码存在内存泄漏(也就是说,它调用
calloc的次数比它调用free的次数多)。编译器不会就此向您发出警告,因为编译器很难(如果不是不可能的话)检测到此类问题。但是,有一些工具(例如 valgrind)将在运行时检测内存泄漏。 -
一个原因:有时您希望能够分配更多内存而无需先释放先前的内存(例如,如果您正在构建一个链表,您不希望编译器强制你释放列表中的第一个节点,只是因为你现在继续创建列表中的第二个节点)
-
当调用任何堆分配函数
malloccallocrealloc, 1) 始终检查 (!=NULL) 返回值以确保操作成功。 2)返回的类型是void*,可以分配给任何指针。强制转换只会使代码混乱,使其更难以理解、调试等
标签: c pointers function-pointers free dynamic-memory-allocation