Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C中的指针问题_C_Pointers - Fatal编程技术网

C中的指针问题

C中的指针问题,c,pointers,C,Pointers,在此代码中,依赖于gdb,p在分配NULL时从0x602010更改为0x0(如我所料) 为什么p在task()内不更改为0x0?指针是一个值,类似于int。可以这样想:如果您将int传递到task()中,并在task函数中对其进行更改,您会期望它发生更改吗?否,因为变量是按值传递的 调用task时,您正在向函数传递一个值的副本(在本例中,它是一个指针)。您要做的是更改指针的值,这意味着您需要一个指向存储该值的位置的指针。这是指向指针的指针,int** 相反: void task(int **p)

在此代码中,依赖于
gdb
p
在分配
NULL
时从
0x602010
更改为
0x0
(如我所料)


为什么p在task()内不更改为0x0?

指针是一个值,类似于
int
。可以这样想:如果您将
int
传递到
task()
中,并在
task
函数中对其进行更改,您会期望它发生更改吗?否,因为变量是按值传递的

调用
task
时,您正在向函数传递一个值的副本(在本例中,它是一个指针)。您要做的是更改指针的值,这意味着您需要一个指向存储该值的位置的指针。这是指向指针的指针,
int**

相反:

void task(int **p)
{
   *p = NULL;
}

传递
p*
的位置

另一个例子,这次使用的是
int
,这可能会更清楚

void makeTen(int *valuePointer)
{
    // Change the variable that valuePointer is pointing to. 
    *valuePointer = 10; 
}

void demoFunction()
{
    int x = 5;

    // x == 5

    // Call this with a pointer to the variable X.
    // We are passing the memory address of the variable x.
    makeTen(&x);

    // x == 10

}

如果您理解这一点,请将
int
更改为
int*
,这样您就可以理解原来的问题。

如果在传递指针后,希望在main中使用
p==NULL
,则需要传递指向指针的指针。比如说

void task(int** p)
{
  *p = NULL;
}
并通过

task(&p);

另外,您应该注意,此代码会泄漏。在调用
malloc
后设置
p=NULL
之前,您应该
free(p)

,因为您误解了指针地址及其指向的对象

void task(int *p)
{
    p = NULL; 
}
此函数将获取指向int的指针,因此,您可以修改存储在其他位置的int值。但int值的变量地址是按值传递的。也就是说,地址存储在本地。将“NuLL”赋值给局部变量不是您想要的

如果将其更改为:

void task(int **p)
{
    *p = NULL; 
}

您将获取指向int的指针。现在地址也被指向,您可以从代码中更改它。指向int的指针必须通过引用传递(这是您的情况)。

在第一个代码段中,当您将NULL赋值给malloc'ed指针时,您正在泄漏内存


在第二个代码段中,您通过指针的值传递指针。因此,这些变化主要不会反映出来

是否有一些代码需要我们检查?提示:指针是按值传递的。如果您在
任务
中更改了
int
,您是否希望更改会传播?如果这是您想要的行为,则需要将指针传递给指针。如果在task()中未更改
p
,则编译器可能已优化掉对值的任何更改。
task(&p);
void task(int *p)
{
    p = NULL; 
}
void task(int **p)
{
    *p = NULL; 
}