我在一个函数中,问题部分已经在这里评论了。
int search(double startpos, double stepsize, double *res){
//Counter this will just make sure the algorithm doesn't search forever.
int i1 = 0;
//This will store results.
res = (double *)calloc(2,sizeof(double)); //Here I am
double *q = (double *)calloc(2,sizeof(double)); //This one too
q[0] = startpos;
q[1] = startpos + stepsize;
while((!compside(q[0],q[1], 1000)) && i1 < 100/stepsize){
//keep going until we find a root
q[0] +=stepsize;
q[1] += stepsize;
i1++;
}
//determine whether a root was found or not.
if(i1>=(100/stepsize))
return 0;
else
return 1;
}
最初我只有 res = calloc(2, sizeof(double));
并且所有 q
都是 res
。但实际情况是,当我运行 gdb 时,它告诉我 res 指向 null (0x0
),并且 q
正确指向数组。
我有几个问题:
为什么我需要对
calloc
进行强制转换?它应该返回一个 void * 指针,但它没有意义,当强制转换被删除时,q 并不指向堆分配!为什么? 我知道它应该隐式转换为double *
。为什么
res
指向null
它是一个双指针,但无论我做什么它都不会指向我分配的堆是吗?
最佳答案
直接回答您的问题:
- 您无需强制转换
calloc()
、malloc()
等函数的返回值。它们返回一个void *
。实际上这样做可能有害。 - 在您的代码中,如果
calloc()
无法分配内存,则res
只能为 NULL,除非您在嵌入式系统上,否则这种情况相当罕见。但是,如果您在调用函数中检查res
,它将保持不变(即,如果它为 NULL,它仍然是 NULL)。
如果您的目的是返回分配给调用者函数的内存,那么您应该传递一个 double **
,如下所示:
int caller ()
{
double *val = NULL;
int rc = 0;
...
rc = called(&val)
...
// Always, always free the memory! (unless you know what you're doing)
free(val);
return rc;
}
int called(double **v)
{
double *r;
int c = 0;
r = calloc(2,sizeof(double));
if (r) {
r[0] = ...;
r[1] = ...;
c = ...;
}
*v = r; // Now the return from calloc() is actually stored in the
// variable val in the scope of the function caller()
return c;
}
此外,您不会对 res 指向的内存执行任何操作,并且当函数返回时该值将丢失,要么您不需要它,要么您错过了分配某些内容。
最后一件事:就像现在一样(没有 free()
),您使用 calloc()
分配的内存只有在您的程序结束后才会返回到系统结束。
关于c - 尽管分配了指针,但指针仍指向 Null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25347255/