1

当我尝试向我的朋友解释一些简单的代码时,发生了一些奇怪的事情:

#include <stdio.h>
int main() 
{
    int x;
    printf("%x\n",x);
}

我已经尝试了数百万次,x 的最后 12 位始终是 0xff0。我已经解除了代码,但仍然无法弄清楚这里发生了什么

我的操作系统是 ubuntu10.10,编译器是 gcc4.7.2

4

4 回答 4

6

读取未初始化的变量是未定义的行为。所以你什么都没有保证。

这包括始终为零、始终均匀、始终不同以及重新格式化硬盘。

于 2012-12-07T17:21:03.790 回答
4

首先,如果该值始终与 0xFF0 匹配,则“低 12 位”是该值,而不是低 3。

至于为什么会发生这种情况,您正在读取一个尚未初始化的变量。这是未定义的行为,当您尝试执行此操作时,任何事情都可能发生,从崩溃到披萨送达。

实际发生的是:x 引用的位置有一些它之前保存的数据。很可能在您的设置中,该变量恰好包含低 12 位为 0xFF0 的数据;在这种情况下,它很可能是与先前的系统调用相关联的数据,在调用您之前由系统完成的处理工作期间main

长话短说:在使用变量之前初始化变量,不要问为什么未初始化的变量具有它们的值。

于 2012-12-07T17:44:03.527 回答
2

该值始终相同,因为您的程序是确定性的。

未初始化变量的值正式“未定义”,但在始终执行完全相同的步骤的程序中,它很可能是可预测的。在这种情况下,事实证明,在 main 之前使用该寄存器或堆栈槽的任何东西都需要您看到的值。

一个程序唯一不具有确定性的情况是它与其他不确定的事物(例如用户、可更改文件或网络)交互。然而,如果没有任何外部刺激,线程程序可能是不确定的。

于 2012-12-07T17:43:20.897 回答
0

我发现它不仅仅是偶数,最后 3 位总是结果是

也许之前存储在堆栈上那个位置的东西是指向堆分配内存的指针的值,或者类似的东西(堆分配的块通常四舍五入到边界,例如8字节边界)。

于 2012-12-07T17:52:50.817 回答