为什么在ubuntu linux中用于c ++的g ++编译器中局部变量初始化为0?

时间:2012-06-21 17:17:03

标签: c++

根据任何有关c ++的书,任何未初始化的c ++局部变量都将包含一个垃圾值。但是,请查看以下程序:

#include<iostream>
using namespace std;
float a;
class A
{
public:
float b;
};
int main()
{
float c;
static float d;
static float e = 0;
A f;
cout<<"\n global a : "<<a<<"\n class variable b : "<<f.b;
cout<<"\n local c : "<<c<<"\n static local d : "<<d
<<"\n static initialized local e : "<<e;
}

如果在ubuntu linux上使用g ++编译,它会提供以下输出:

global a : 0
class variable b : 6.94896e-36
local c : 0
static local d : 0
static initialized local e : 0

奇怪的是它为局部变量c提供了一个0值,而这应该是未初始化的并包含一些垃圾值。相同的程序与Windows的visual c ++的工作方式不同,并为c提供了一个垃圾值,这是你所期望的。

2 个答案:

答案 0 :(得分:10)

本地变量c保留未初始化。这意味着,正如您所说,它具有垃圾值。该对象可能具有任何值,包括0。零是有效的“垃圾价值”。通常,不允许您从尚未初始化的对象中读取。

为什么c的值为零?可能是编译器(g ++)在输入函数时对堆栈进行零初始化,以“帮助”程序“正确”执行,即使它使用了未初始化的变量。或者,可能是操作系统在将内存页面提供给您的程序之前将其初始化为零。或者,也许在main之前调用的函数在现在由c占用的字节数组中存储零值,因此它的值为零。


使用Visual C ++编译的二进制文件的行为取决于它的编译方式。在发布二进制文件中,性能比可调试性更重要,在输入函数时不会隐式初始化堆栈,因此c将保持未初始化状态并具有垃圾值。

在调试二进制文件中,可调试性更重要,所有局部变量都使用字节0xcc进行初始化。这可以帮助您跟踪和调试未初始化变量的使用情况。类似地,调试堆使用字节0xcd初始化新分配的存储,并在分配和解除分配时使用different bit patterns填充内存,以帮助您调试程序的状态。

答案 1 :(得分:1)

读取未初始化的变量是未定义的行为,但总的来说,你会这样做 得到该位置的内存中的位数 代表(可能是诱捕NaN)。在这种情况下,内存中 问题从来没有被用于任何其他事情,当你得到记忆 为了安全起见,系统通常会被清除 原因。将变量放在一个函数中,调用其他几个 首先发挥作用,然后看看你得到了什么。