1

根据任何有关 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 提供了一个垃圾值,这是您所期望的。

4

2 回答 2

10

局部变量c初始化。正如您所说,这意味着它具有垃圾值。 该对象可以具有任何值,包括0. 零是有效的“垃圾值”。一般情况下,不允许读取尚未初始化的对象。

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


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

在调试二进制文件中,可调试性更重要,所有局部变量都用 byte 初始化0xcc。这可以帮助您跟踪和调试未初始化变量的使用情况。类似地,调试堆使用 byte 初始化新分配的存储,并在分配和释放内存时使用不同的位模式0xcd填充内存,以帮助您调试程序的状态。

于 2012-06-21T17:23:35.230 回答
1

读取未初始化的变量是未定义的行为,但一般来说,您将获得该位置的内存中的位碰巧表示的任何值(这可能是一个陷阱 NaN)。在这种情况下,有问题的内存从未用于其他任何用途,并且当您从系统获取内存时,出于安全原因,它通常会被清除。将变量放在一个函数中,先调用几个其他函数,然后看看你得到了什么。

于 2012-06-21T17:25:27.863 回答