【问题标题】:Why does one variable get the same value as another value为什么一个变量的值与另一个值相同
【发布时间】:2020-05-28 22:35:28
【问题描述】:

因此,函数“thinkOfANumber”为变量“x”赋予值 108。然后,我们进入函数“mindReading”,该函数具有未赋予任何值的变量“secrets”。但不知何故,它得到了与“x”相同的值。我的猜测是它与堆栈和内存有关。谁能帮我解释一下?

代码:

void thinkOfANumber(){
    int x = 108;
    printf( "This function thinks of a secret number (%d)\n", x);
}

void mindReading(){
    int secret;
    printf( "This function believes that the other functions secret is: %d!\n", secret); //Prints 108
}

void main(){
    thinkOfANumber();
    mindReading();
    return 0;
}

【问题讨论】:

  • Undefined behaviour 以神秘的方式工作,使用未初始化的变量是 UB..
  • 旁注:return 0;void main() 函数中看起来很奇怪。我建议更改返回类型,因为main 必须返回int。 C++ 标准是这么说的。
  • 尝试在启用优化的情况下编译此代码。这足以打破它,请参阅:wandbox.org/permlink/abDKQVpFjjMxbnnK
  • 这绝对是未定义的行为。但它恰好起作用,因为secret 很可能与x 共享相同的堆栈地址。但是使用-O3 优化进行编译,一切都会消失。
  • 我曾经遇到过这样的事情,通过在源代码中添加或删除 cmets 来改变行为。未定义的行为可以做任何事情,包括时间旅行(参见stackoverflow.com/questions/24527401/…

标签: c++


【解决方案1】:

从默认初始化的int 读取是未定义的行为,因为它具有不确定的值。

secret 读取时,编译器可能从一个寄存器中读取值,而该寄存器恰好保存了x 的值。

无论如何,这不是你可以依赖的行为,即使在同一台机器上,使用相同的编译器,使用相同的编译标志等。

【讨论】:

    【解决方案2】:

    您的变量未初始化,将给出未定义的行为。这可能包括但不限于 -

    • 您的程序每次运行都会产生不同的结果。

    • 您的程序始终产生相同的结果。

    • 您的程序适用于某些编译器,但不适用于其他编译器。


    在您的情况下,未初始化变量可能指向存储初始化变量x的地址的内存位置。但至少在我看来,情况并非每次都如此,并且会在不同的编译器或不同的机器上以未定义的方式运行。

    记住始终初始化变量

    【讨论】:

      【解决方案3】:

      C/C++ 局部变量在需要时被分配内存。这里secret 变量没有分配任何内存。所以这里其实就是按照x的地址。看这里的代码,

      #include<stdio.h>
      
      void a(){
          int x = 40;
          int y=30;
          printf( "This function thinks of a secret number (%d)\n", x);
      }
      
      void b(){
          int xx;
          int z;
          printf( "This function believes that the other functions secret is: %d !\n", xx);
          printf("%d\n",z);
      }
      
      int main(){
          a();
          b();
          return 0;
      }
      

      这里secret 的值是xz 的值是y。如果您在函数b 中更改secret 的值,那么这将为变量secret 分配一个新内存。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-01-04
        • 1970-01-01
        • 1970-01-01
        • 2021-09-29
        • 2015-09-21
        • 1970-01-01
        • 2023-01-13
        • 2012-07-23
        相关资源
        最近更新 更多