这里我有代码
#include <stdio.h>
void what_in_variable1(void);
void what_in_variable2(void);
void what_in_variable3(void);
int main(void)
{
what_in_variable1();
what_in_variable2();
what_in_variable3();
return 0;
}
void what_in_variable1(void)
{
int a;
int b;
int c;
printf("a znachenie %d\n", a);
printf("b znachenie %d\n", b);
printf("c znachenie %d\n", c);
}
void what_in_variable2(void)
{
int d;
int e;
int f;
printf("d znachenie %d\n", d);
printf("e znachenie %d\n", e);
printf("f znachenie %d\n", f);
}
void what_in_variable3(void)
{
int q;
int o;
int p;
printf("q znachenie %d\n", q);
printf("o znachenie %d\n", o);
printf("p znachenie %d\n", p);
}
代码返回消息
a znachenie 0
b znachenie -134327328
c znachenie 32767
d znachenie 0
e znachenie -134327328
f znachenie 32767
q znachenie 0
o znachenie -134327328
p znachenie 32767
显然,这不是分配为变量之前内存中的数据,否则所有数字都会不同。出于同样的原因,这些不能是分配给变量的存储单元的地址。在这种情况下,函数中声明的最后一个变量始终等于32767,在其之前声明的变量始终等于-134327328,其前面的变量始终等于0。也就是说,如果他只是宣布的话a,那就b已经a是-134327328并且b本来就是32767。
或者代码是否经过编译,以便在人工赋值之前总是为变量分配一些默认值,具体取决于变量声明的顺序?
如果是这样,是否有可能以某种方式编写一个代码,在人们赋值之前不会为变量分配默认值,但能够看到最初存在的内容?也许另一个程序之前曾使用过这个存储单元,并在那里留下了一些有趣的数据——cookies、密码等。
短的
标准C:没什么可说的,未定义的行为。
GCC 编译器:堆栈中的垃圾进入变量,这在所有三个函数中都是相同的。
另一个编译器可能会说不同的话。
操作系统有时会确保一个程序不会从另一个程序接收数据。如果您使用敏感数据,则应在使用后将其删除。
长的
你违反了 C 语言的规则:在给变量赋值之前你不能读取它。这是未定义的行为,意味着程序可以做任何事情。 C 语言仅此而已。
但是具有特定设置的特定编译器可以执行特定的操作。让我们看看 GCC 对您的代码做了什么:
该程序的汇编器位于其中
temp.s。main连续调用函数:让我们比较一下两个函数。除了打印字符串引用之外,它们具有几乎相同的代码。我们对说明感兴趣
movl -12(%rbp), %eax,,movl -8(%rbp), %eax。movl -4(%rbp), %eax它们将变量从堆栈复制到寄存器
eax。rbp- 指向栈顶,offsets-12,-8,-4指的是栈上的不同位置。偏移量之间的距离恰好是四个字节,这是整个变量的大小。两个函数从堆栈上的同一位置读取字节。因此,他们读取相同的随机值:
what_in_variable1what_in_variable2