C代码:
int a;
printf("\n\t %d",a); // It'll print some garbage value;
那么如何将这些垃圾值分配给C中窗帘后面的未初始化变量?
这是否意味着C首先将内存分配给变量'a'然后该内存位置的内容变为'a'的值?或其他什么?
答案 0 :(得分:9)
这是否意味着C首先将内存分配给变量'a'然后该内存位置的内容变为'a'的值?
完全!
基本上,C不会做任何你不告诉它。这既是它的优势,也是它的弱点。
答案 1 :(得分:6)
这是否意味着C首先将内存分配给变量'a'然后是什么 有没有那个记忆位置成为'a'的价值?要么 别的什么?
正确。值得一提的是,int a
等自动变量的“分配”几乎不存在,因为这些变量存储在堆栈或CPU寄存器中。对于存储在堆栈中的变量,在调用函数时执行“分配”,并归结为一个指令,该指令将堆栈指针移动一个在编译时计算的固定偏移量(函数使用的所有局部变量的组合存储,四舍五入到正确对齐)。
分配给CPU寄存器的变量的初始值是寄存器的先前内容。由于这种差异(寄存器与内存),有时会发生在编译时没有优化的情况下正常工作的程序在打开优化时编译。未初始化的变量,以前指向恰好为零初始化的位置,现在包含以前使用同一寄存器的值。
答案 2 :(得分:1)
int a
;
在声明变量时,会分配内存。但是未分配此变量,这意味着变量a
未初始化。如果此变量a
仅被声明但在程序中不再使用,则称为垃圾值。
例如:
int a, b;
b=10;
printf("%d",b);
return 0;
此处仅声明但不再分配或初始化。所以这叫做垃圾值。
答案 3 :(得分:0)
最初内存中有一些值,这些值是未知值,也称为垃圾值, 当我们声明一个变量时,根据我们在声明时指定的数据类型为变量保留了一些内存,所以内存初始值是未知值,如果我们初始化一些其他值,那么我们的值将在该内存位置。
答案 4 :(得分:0)
这是否意味着C首先将内存分配给变量'a',然后该内存位置处的值变成了'a'的值?
不,并不意味着那样。
当未初始化对象时,C标准不提供有关如何确定其值的任何计划。不仅如此,程序不需要表现为对象具有任何固定值。好像为它保留的内存没有处于任何固定状态,只是在波动中,它可以变化。
以下是有关C 2018的特定规则:
malloc
分配的对象为7.22.3.4 2,对于由realloc
分配的额外空间为7.22.3.5 2,对于aligned_alloc
为7.22.3.1 2。初始化其他对象,例如具有静态存储持续时间的对象。这意味着在每个实例中使用一个对象,C标准不强加对其使用值的任何要求。不需要与以前的使用相同。该程序的行为就好像它没有任何固定值。当它多次使用时,该程序可能会好像每次都有一个不同的值一样工作。例如,C标准将允许printf("%d %d %d\n", a, a, a);
打印“ 34 -10200773 2147483204”。
发生这种情况的一种方式是,在尝试编译代码int a; printf("%d %d %d\n", a, a, a);
时,编译器无处可得a
,因为它从未被赋予任何固定值。因此,编译器不会生成无用的指令,而不是生成无用的指令以将数据从未初始化的内存移动到传递参数的位置。然后printf
被调用,并且传递参数的寄存器或堆栈位置包含了它们先前的所有数据。这很可能是printf
打印的三个不同的值。因此,它看起来像输出的观察者,好像a
在printf("%d %d %d\n", a, a, a);
中有三个不同的值。
(此外,使用未使用其地址的具有自动存储期限的未初始化对象的值显然是未定义的行为,因为6.3.2.1 2关于将对象转换为其值的说明是,“如果左值指定一个具有自动存储期限的对象,该对象可能已经用寄存器存储类声明了(从未使用过其地址),并且该对象未初始化(未使用初始化程序声明,并且在使用前未对其进行任何分配),该行为因此,当存在满足这些条件的对象时,使用其值可能会完全破坏程序;它不仅可能在不同的时间具有不同的值,而且程序可能会中止,并沿着与预期不同的分支进入,而不是在源代码中有printf
时调用printf
,依此类推。)