我在一个函数中,问题部分已经在这里对它们进行了评论。
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
它是一个双指针但是无论我做什么它只是没有指向我为它分配的堆?
答案 0 :(得分:1)
直接回答您的问题:
calloc()
,malloc()
和朋友的回报。他们返回void *
。实际上这样做可能是有害的。res
中只有calloc()
无法分配内存时才能为NULL,除非您在嵌入式系统上,否则这种情况并不常见。但是,如果你在调用函数中检查res
,它将保持不变(即如果它是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()
分配的内存才会返回给系统。