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 用のビジュアル 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 に答える