c - 尽管分配了指针,但指针仍指向 Null

标签 c pointers

我在一个函数中,问题部分已经在这里评论了。

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 正确指向数组。

我有几个问题:

  1. 为什么我需要对 calloc 进行强制转换?它应该返回一个 void * 指针,但它没有意义,当强制转换被删除时,q 并不指向堆分配!为什么? 我知道它应该隐式转换为 double *

  2. 为什么res指向null它是一个双指针,但无论我做什么它都不会指向我分配的堆是吗?

最佳答案

直接回答您的问题:

  1. 您无需强制转换 calloc()malloc() 等函数的返回值。它们返回一个 void *。实际上这样做可能有害。
  2. 在您的代码中,如果 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/

相关文章:

c - 如果我已经为字符串 b 赋值,则无法将字符串 a 复制到字符串 b

c - 用 C 编程 : Changing member value of struct gives segfault

c - 堆栈头部和尾部更新为相同的值但仅在 head-C 编程上调用更新

c - 如何在 c 中执行多个读/写 HDD/USB 字节

c - 从 C 中的二进制文件中读取 block 字节

android - 在 eclipse android 应用程序中使用 native 代码

c - 指针初始化和两个指针指向同一个地址

C++ 指针和引用数据类型

c - 在机器上查找可用的网络端口

无法在启用的 CPU 上使用 SSSE3