2009-07-17 16 views
8

コードサンプルは、物事を説明する必要があります:それはスタンドとしてC++:メンバポインタが初期化されていますか?

class A 
{ 
    B* pB; 
    C* pC; 
    D d; 

    public : 
    A(int i, int j) : d(j) 
    { 
     pC = new C(i, "abc"); 
    } // note pB is not initialised, e.g. pB(NULL) 

    ... 
}; 

明らかPBは、安全(クリア)であることを明示的にNULLに初期化が、しなければならない、を建設した後PBの値は何ですか?デフォルトは初期化されていますか(ゼロですか?)かどうか(つまり、不確定なものとメモリ内のもの)です。私はC++の初期化がかなりのルールを持っていることを認識しています。

私はデフォルトでは初期化されていないと思います。 Visual Studioのデバッグモードで実行されているので、pBは0xcdcdcdcdを指しています。つまり、メモリはヒープ上にnew'dされていて初期化されていません。ただし、リリースモードでは、pBは常にNULLを指します。これはちょうど偶然のことなので、それに頼ることはありません。またはこれらのコンパイラは私のために初期化しています(それが標準にない場合でも)?また、Solaris上でSunのコンパイラでコンパイルすると、NULLと思われます。

私は本当にどちらか一方の方法で標準への具体的な参照を探しています。

ありがとうございました。

+4

不確定(および一部のコンパイラは警告するでしょうが)、私はC++標準を手に入れません。 – ephemient

+4

Bは野生の中へのランダムなポインタです。注意。デバッグモードでは、ほとんどのコンパイラはそれをNULLに初期化します(おそらくデバッグに役立ちます)。しかし、リリースモードでは、以前にメモリにあった値を持ちます。 –

答えて

11

彼標準fromt関連する通路である。

所与非静的データメンバーまたは 基本クラスでない場合は塩基およびメンバー[class.base.init]

4を初期化

12.6.2 MEM-初期化子リストでMEM-
イニシャライザ-IDによって指定され、その後、エンティティ--If

は(おそらくCV修飾)の非静的データ 部材であり、 クラスタイプ(またはその配列)または基本クラスであり、エンティティクラス が非PODクラスである場合、エンティティはデフォルトで初期化されます(dcl.init)。 エンティティがconst修飾型の非静的データメンバである場合、 エンティティクラスには、ユーザが宣言したデフォルトのコンストラクタがあります。

- それ以外の場合、エンティティは がに初期化されていません。エンティティがconst修飾された型または参照型の であるか、const修飾型のメンバを直接的に(または直接的にまたは に)含む(または可能であれば)PODクラス型(またはその配列)である場合、プログラムは ill- となります。 Xのメンバー

が コンストラクタのMEM-初期化子に指定されていない、また
デフォルト初期化、また実行中に を初期化もされていない場合 クラスXのコンストラクタへの呼び出しが、完了した後


のコンストラクタの本体には、 の不定値があります。

+2

です。初期化されておらず、何かを指すことができます。デバッグ・ヒープ・ライブラリー用の実装、つまりfdfdfdfdによってコンテンツが埋められます。 – xtofl

1

これは、あなたがalloc'dのメモリに何が含まれているかについての期待を持っていなかったときの良い古いCの遺物だと思います。標準がC++に進むにつれ、この「コンベンション」が維持されました。 C++コンパイラが開発するにつれて、個々の作者はこの問題を「修正」するためにそれを取った。したがって、お客様のマイレージは、ご希望のコンパイラによって異なる場合があります。

"0xcdcdcdcd"はコードをデバッグするのに役立つ容易に識別可能なパターンに見えます。そのため、リリースモードでは表示されません。

これはちょっとしたお手伝いと幸運を祈っています。

0

初期化されていないポインタは何かを指すことができます。いくつかのコンパイラベンダがあなたを助け、0または0xcdcdcdcdなどを指すようにします。

コードが安全で移植性が高いことを確認するには、ポインタを常に初期化する必要があります。 0または有効な値に設定します。

C* pc = 0; 

または

C* pc = new C(...); 

あなたは常に0へのポインタを初期化する場合、これは安全である:

if (!pc) 
    pc = new C(...); 

あなたが初期化伝える手立てを得なかっましたその後、初期化していない場合および初期化されていないポインタを区別します。

脇に、C++にはNULLというものはありません。ほとんどのコンパイラはNULLを0と定義していますが、それを使用するには移植性がないと考えられます。新しいC++ 0x標準では、新しいキーワードnullptrが導入される予定です。そのようになると、最終的に移植可能なヌルポインタ定数が得られます。

0

pBの値は不定です。一貫して同じ値であっても、そうでなくてもかまいません。通常は、Aの特定のインスタンスを割り当てる前に、以前はメモリ内の同じ場所にあったものに依存します。ここ

0

初期化されていないポインタは基本的にランダムな値を含むことができますが、コンパイラの中には、特にデバッグモードでそれらを0や他の認識可能な値で埋める傾向があります。

IMHOこれはC++の「あなたが使用していないものを支払わない」ためです。それを重要視しないと、コンパイラは変数を初期化するための費用を負担する必要はありません。もちろん、ランダムポインタを追いかけると、次回にそれを初期化するのが賢明かもしれません...

+0

「あなたが使っていないものを支払ってはいけませんか?」という意味ではありませんか? – Imagist

+0

Errr ....はい。それを指摘してくれてありがとう。 –

4

C++0x standardセクション12.6.2.4によると、あなたのポインタ変数の場合は、それを初期化子リストに含めないでください。コンストラクタの本体に設定しないと、不確定な値になります。 0xCDCDCDCDと0は、他のものと同様に2つの可能な値です。 :-)

0

あなたが使っている言語について何か勉強しないことをお勧めしますが、この場合、pBが初期化されているかどうかは有益な情報ではありません。ちょうどそれを初期化してください。自動的に初期化された場合、コンパイラは余分な初期化を最適化します。そうでない場合は、余分なプロセッサ命令を1つ追加して、潜在的なバグを完全に防ぎます。

関連する問題