2011-09-19 52 views
3

我玩C++在VisualStudio2010分配指向未初始化变量的指针会改变它的值吗?

请解释为什么会发生:

int a, b; 
int *p, *q; 
cout << a << " " << b; 

打印出 “0”。这是可以理解的,未初始化的整数应该是0; 但

int a, b; 
int *p, *q; 
p = &a; 
cout << a << " " << b; 

输出为“1792816880 0”

所以,如果我给你的指针从默认初始化的变量它的变化值。 为什么?

编辑澄清:问题不是关于未初始化的变量

int a; int *p; 
cout << a; // would be 0, because it's loacal variable 
p = &a; 
cout << a; //not 0; 

价值如何得到的一个指针可以改变它的价值?当我们初始化变量时,我们分配空间,有些位,它们可能是任何东西,但是“p = & a”它实际上是否改变了这个空间中的位?

+0

有趣。在Fedora 15 x64_86的G ++ 4.6.0下也会出现类似的情况。 – trojanfoe

+2

增加项目设置中的警告级别。这将检测未初始化变量的用法。 – Stephan

+0

不是。 未初始化的整数应参照本地变量 –

回答

6

那么它是可以理解的,未初始化的整数应该是0

有没有这样的保证,它取决于存储类,如果你的int是局部变量它有一个自动存储并且不必为0.

访问单元化变量导致未定义行为和您的代码导致未定义的Beh avior。一旦出现未定义行为,所有投注都将停止,并且行为无法解释。

关于未定义行为,

C++标准部1.3.24状态:

允许不确定的行为的范围从具有不可预知的结果完全无视的情况下,在一个或翻译程序执行期间表现有记录的环境特征(有或者没有发布诊断消息),终止翻译或执行(通过发布诊断消息)。

编辑:
鉴于上述情况,这是不确定的行为与一个人不应该写依赖于这种行为的任何代码,事实上一个也别想写这样的代码。我发现它无关紧要地深入到所有这些编译器的实现中,以此来解释它为什么会起作用。

如果有人发现此回复头重脚轻,您可以自由下注。如果downvote计数超过upvotes,我会知道答案是不受欢迎的,我会删除它。

+0

+1。 –

+0

我不认为“未定义行为的防守回答了这个问题确实它是0 – trojanfoe

+2

@trojanfoe这是唯一可能的答案。程序的行为是不确定的,所以几乎可能发生任何事情。 –

2

没有定义未初始化值的值。没有默认值。任何价值都可能出现。

你可以改变这些垃圾软件就会给你一个答案,你的不定值的查询的潜在价值的任何看似无关的操作。

底线是,不要推测应该发生什么未定义的行为。这是简单的未定义 - 不要写未定义行为的代码。

3

这是C++中的“未定义行为”。

当你不用C++初始化一个变量时,它并不总是为零。这只是偶然。内存被分配,并且之前在该内存位置中的垃圾值将被输出,直到它被初始化。

0

C++不会初始化声明变量,它只是为它们分配RAM内存。如果你使用指针或者不使用指针,它们可以在初始化之前使用任何值。 您应该始终在使用前初始化您的变量。

+0

RAM?这些变量都存储在堆栈中! – trojanfoe

+0

@trojanfoe:你说堆栈不是RAM? – Stephan

+0

当然没有,但它的分配方式并不一样。 – trojanfoe

0

在C++中,未初始化的本地整数不保证为0。他们是“垃圾”,因此,他们可以是包括0

2

这是不确定的行为,但这里是一些炒作,以什么可能发生的任何值:

在第一个代码示例,该变量的地址是从来没有被采纳过,因此编译器选择将它们保存在寄存器中并且它们永远不会存在于主存储器中,并且寄存器的值恰好为0.

在第二个代码示例中,在内存中(在堆栈上),以便它可以有一个地址。恰巧现有的数据存在一些随机垃圾。

1

你有一堆没有写入的变量,永远。编译器可能决定不为这些变量分配存储空间。这可能看起来很苛刻,但这是合理的:现代编译器在细粒度级别上分配变量存储,并且某些分支上可能未使用某些变量。当不需要时为什么要分配内存?

现在,如果您从未分配内存的“变量”读取数据会发生什么,因为您从未写入过内存?你会得到一些随机数据,很可能是另一个变量。或者是段错误 - 未定义行为有很多种形式。

现在拿你的第二个例子:在这里你写入一个变量,p。由于a不需要任何内存分配(没有写入),所以它可能很好地别名p。和p值,重新解释为int很可能是1792816880.

相关问题