如何解释这个奇怪的输出?关于指针和临时变量

时间:2012-10-24 03:16:35

标签: c++ c pointers

谁知道为什么输出是这样的?
虽然使用这样的指针是错误的,但我仍然想知道它为什么会这样做。

int* foo()
{
    int a=9;
    int *p=&a;
    //definitely not right to return a pointer to an invalid varible
    return p;
}
int main(int argc, char* argv[])
{
    int *p=foo();
    cout<<*p<<endl;//9
    cout<<*p<<endl;//2357228
    *p=2;
    cout<<*p<<endl;//2
    (*p)++;
    cout<<*p<<endl;//2357229
    cout<<*p<<endl;//2357228
    cout<<*p<<endl;//2357228
    (*p)++;
    cout<<*p<<endl;//2357229
    cout<<*p<<endl;//2357228

    return 0;

}

3 个答案:

答案 0 :(得分:2)

返回对函数本地变量的指针/引用会导致未定义行为。保证本地/自动变量是活动的,并且仅在范围({})中有效,其中定义的范围不超出该范围。

未定义的行为意味着程序可以显示任何行为,并且允许通过C / C ++标准执行此操作。在未定义行为发生后尝试查找观察到的行为的推理是没有意义的,因为此行为可能/可能不会保持一致或不能依赖。

从好的方面来说,任何优秀的商业编译器都会为您提供有关此类代码的警告。

答案 1 :(得分:1)

  

虽然使用这样的指针是错误的,但我还是愿意   理解为什么它的行为方式。

因为p指向堆栈内存中的某个位置,该位置不断被cout的&lt;&lt;方法。每次使用cout时,p的值都可能会改变。

这样的代码很危险,因为它可能会破坏堆栈并导致程序崩溃。

答案 2 :(得分:0)

您需要记住的是a和p都是范围级变量。因此,返回仅存在于堆栈中的变量的地址(但未在堆上动态分配)是未定义的行为。因为一旦离开那个地址空间,我们就不再知道写到那里的东西了。因此,返回指向局部变量的指针是未定义的行为。