指针给出了意想不到的价值

时间:2016-08-03 15:24:57

标签: c pointers initialization undefined-behavior

void first(){
    int x;
    int *p;
    p= &x;
    scanf("%d",p);
    printf("The value in x or *p is: %d\n",x);
}


void second(){
    int x;
    int *ptr;
    scanf("%d",&x);
    printf("The value in *ptr is: %d\n",*ptr);
}


int main(){
    first();
    second();
}

在上面的代码中,second()函数是未命中行为。我为x变量赋予了什么值,该值已分配给*ptr以及x。为什么呢?

2 个答案:

答案 0 :(得分:6)

您没有为p分配一个值,因此它仍然未初始化。试图取消引用该指针调用undefined behavior

p一个值,你就会得到你期望的结果:

int *p = &x;

您的代码仍在打印正确值的事实是该未定义行为的一部分。未定义行为可以表现出来的方式之一是代码似乎正常工作,但是看似无关的更改会导致代码中断。

在这种特殊情况下,函数firstsecond分别定义了相同类型和相同顺序的2个局部变量。在对first的调用完成后,包含该函数的xp值的内存仍包含这些值,但还没有其他函数调用来覆盖它们。

然后在second之后立即致电firstx中的变量ptrsecond最终在x中使用与pfirst相同的内存。由于ptr未初始化,因此它仍然包含旧值,该值首先是x的地址,恰好与xsecond的地址相同

同样,这是未定义的行为,因此您无法始终依赖于这种情况。如果您将另一个变量添加到first或在firstsecond之间调用另一个函数,则会修改first以前使用的堆栈内存。然后,内存将包含一些其他值,您可能会打印垃圾值或核心转储。

如果使用不同的编译器或不同的编译器选项编译,相同的代码可能会给出不同的结果。例如,另一个编译器可能选择将每个函数中的变量以不同的顺序放在堆栈上,或者它可以决定在函数返回后将函数使用的堆栈清零。

答案 1 :(得分:0)

int *p=&x;

x的地址存储在p中。

printf("%d",*p);

由于p的地址为x,* p基本上意味着您将前往p指定的位置并拾取该项,即x的值。