第一次取消引用后,指针指向的值会发生变化

时间:2015-01-07 08:05:09

标签: c pointers

我试图在“init_pointer”函数中初始化整数指针“p”。函数返回后,我打印指针和解除引用的值两次。第一个取消引用打印预期值100,但第二个取消引用打印随机值。

#include<stdio.h>

    void init_pointer(int d, int **c){
            (*c) = &d;
    }

    int main(){
            int x = 100;
            int *p;

            init_pointer(x,&p);

            printf("pointer = %p, value = %d\n",p,*p);
            printf("pointer = %p, value = %d\n",p,*p);

            return 0;
    }

输出

pointer = 0x7fffb4d4b9ac, value = 100
pointer = 0x7fffb4d4b9ac, value = 32567

3 个答案:

答案 0 :(得分:9)

该函数已将值复制到init_pointer(int d, int **c)

中的新局部变量

d位于init_pointer的本地,由main x传递。 xd都是单独的变量,其地址不同。访问d之外init_pointer的地址将导致Undefined Behavior

调用这样的函数是没有意义的,但这样可行:

void init_pointer(int *d, int **c)
{
        (*c) = d;
}

int main()
{
        int x = 100;
        int *p;

        init_pointer(&x,&p);

        printf("pointer = %p, value = %d\n",p,*p);
        printf("pointer = %p, value = %d\n",p,*p);

        return 0;
}

输出:

pointer = 0xbfde132c, value = 100
pointer = 0xbfde132c, value = 100

答案 1 :(得分:2)

void init_pointer(int d, int **c){
        (*c) = &d;
}

此处*c指向init_pointer()内的本地副本init_pointer()返回后,地址无效,p中的main()指向已释放的地址。

答案 2 :(得分:0)

在init_pointer中,您将参数d的地址分配给* c。参数的地址是堆栈地址。

在第一次调用printf时,堆栈(尽管已解除分配)仍然完好无损,因此p指向堆栈上丢弃的参数d,它仍然具有值100,并且* p首先被推入堆栈。

在第二次调用printf时,第一次调用已覆盖堆栈。虽然指针仍然指向同一个地址,但是它的值已被p的推动覆盖。因此打印p(地址)。

注意:使用&#34;堆栈(尽管已取消分配)&#34;我的意思是sp的堆栈(英特尔;向下增长)。此外,堆栈可以在任何时候被覆盖,例如,当中断发生时。