C中的指针问题

时间:2012-08-21 20:37:23

标签: c pointers

在此代码中,当gdb被分配时,依赖p0x6020100x0更改为NULL,(正如我所料)

#include<stdio.h>
#include<stdlib.h>

int main()
{
    int a = 10;

                        // gdb output
    int *p = (int *) malloc(sizeof(int));   // p = (int *) 0x602010
    p = NULL;               // p = (int *) 0x0
    p = &a;                 // p = p = (int *) 0x7fffffffe15c           

    return 0;
}

但是,当pmain()之外的task()之外更改时,我猜它不会更改为0x0而我不会这样做:

#include<stdio.h>
#include<stdlib.h>

void tast(int *p);

void task(int *p)
{

/*
 before
 (gdb) p p
 $1 = (int *) 0x7fffffffe15c         (same as variable a)
 (gdb) p &p
 $2 = (int **) 0x7fffffffe128
*/

    p = NULL;

/*
 after
 (gdb) p p
 $3 = (int *) 0x7fffffffe15c        no change?
 (gdb) p &p
 $4 = (int **) 0x7fffffffe128
*/    
}

int main()
{
    int a = 10;

                        // gdb output
    int *p = (int *) malloc(sizeof(int));   // p = (int *) 0x602010
    p = NULL;               // p = (int *) 0x0
    p = &a;                 // p = p = (int *) 0x7fffffffe15c

    // it is possible to change what p points to 
    // after calling task()?
    task(p);

    // p will be NULL?          

    return 0;
}

为什么p在task()中没有变为0x0?

4 个答案:

答案 0 :(得分:2)

指针是一个值,就像int一样。可以这样想:如果你将int传递给task()并在task函数内部进行了更改,那么它会发生变化吗?不,因为变量是按值传递的。

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

的指针

代替:

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

task(&p);

传递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 *,您将了解原始问题。

答案 1 :(得分:1)

在第一个片段中,当你为malloc指针指定NULL时,你正在泄漏内存。

在第二个片段中,您将指针传递其值。所以这些变化不会反映在主要方面。 This explains the problem.

答案 2 :(得分:0)

如果在传递指针后期望main中的p == NULL,则需要将指针传递给指针。例如

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

并传递

task(&p);

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

答案 3 :(得分:0)

因为您误将指针地址及其指向的对象误认为。

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

此函数将获取指向int的指针,因此,您可以修改存储在其他位置的int值。但是,int值的变量的地址是按值传递的。这意味着,地址存储在本地。将“NuLL”分配给局部变量并不是您想要的。

如果您将其更改为:

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

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