【问题标题】:How could "printf (cout)" change uninitialized local variable? [duplicate]“printf (cout)”如何改变未初始化的局部变量? [复制]
【发布时间】:2016-02-21 07:58:44
【问题描述】:

我犯了一个错误,在函数中使用了未初始化的局部变量,碰巧发现一行“cout”可以改变未初始化的值。为简化起见,我将问题展示如下。

#include <stdio.h>

void foo(void){
  int i;
  printf("%d\n", i);
  i = 777;
}
int main(void){
  foo();
  //cout << "hello!" << endl;
  foo();
  return 0;
}

我注释掉的行会将输出从 (unknown#;777) 更改为 (unknown#;hello!;0)。有人可以帮忙解释一下吗? 谢谢。

【问题讨论】:

  • 为什么这被标记为 C++?
  • 您正在打印一个未初始化的变量?您认为它可能是什么价值 - 可能是什么?
  • 因为cout是C++?
  • 无法定义未定义的行为 - 即。查看未初始化的变量正在查看任意内存 - 该内存中的内容可能取决于之前执行的代码,但可能会或可能不会重复,具体取决于您的环境
  • i 被(至少大多数编译器)放置在堆栈上,并且您读取的值恰好在那里。函数调用(例如输出到 cout)也使用堆栈,因此 cout 会以这种方式更改堆栈。

标签: c++


【解决方案1】:

这是因为堆栈行为。

第一种情况:

int main(void){
  foo();
  foo();
  return 0;
}

第一个foo() 构建堆栈并用777 初始化i 的位置并保持原样。然后,对foo() 的第二次调用位于同一堆栈结构上,其中i 的位置仍然是777。所以,在这种情况下,printf 打印出777

第二种情况:

cout &lt;&lt; "hello!" &lt;&lt; endl实际上是在调用两个函数:

cout.operator<<("hello!");
cout.operator<<(endl);

这会覆盖我们之前创建的堆栈结构。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多