3

場合によっては、valgrindなどのツールを使用して、ポインター変数の初期化を忘れたかどうかを確認できます。しかし、なぜ現代のコンパイラーは、再現するのが難しいこのよくある間違いから私たちを解放しないのでしょうか?

4

3 に答える 3

4

初期化は必ずしも望ましいとは限りません。

  • パフォーマンス上の理由から。メモリの初期化には時間がかかりますが、これは必要ない場合があります。望ましいパフォーマンスを達成するために一定の時間割り当てに依存するアルゴリズムもあります(初期化は線形時間です)。Dはこれを認識しますが、異なる(おそらくより良い)アプローチを採用しています。変数はデフォルトで初期化されますが、初期化を防ぐための特別な構文があります。

  • 正しいデフォルト値がない場合があります。静的分析またはランタイムデバッグ機能は、変数が初期化なしで使用されていることを検出するのに役立ちます。デフォルトでそれらにいくつかの(誤った)値を割り当てるだけで、これらを使用して検出されるバグを隠すことができます。

于 2013-02-16T04:33:20.183 に答える
2

あなたの質問にはいくつかの側面があります。まず第一に、標準はこの振る舞いを義務付けていません。しかし、それが標準に違反しない場合、それはおそらく可能です。実際、たとえばMSVCでのデバッグビルドは、まったく逆のことを行い、ある魔法の値では0なく、ある魔法の値で初期化します。別の魔法の値を使用して、「解放された」メモリを埋めます。繰り返しになりますが、これはデバッグビルドに固有であり、特定のクラスのエラーを検出するのに役立ちますが、他のバグを隠したり、コードベースの所在をわか​​りにくくしたりする可能性があります。

しかし、ここではパフォーマンスの問題がより重要になると思います。整数と浮動小数点数を初期化する場合、ヒープとスタックの両方ですべての種類の構造体または配列を使用しないのはなぜですか?これに伴う問題は、もちろん、プログラムを作成し、それにデータを読み取るためのバッファーを割り当てる場合、xバイトを読み取ることがわかっていて、バッファーがxのみであることがわかっている場合、最初にバッファーをゼロにするために時間を無駄にする必要があることです。バイト長?

私は同意します。DebianSSH災害のようなこの「ランダムな」動作に依存することは正しくありませんでしたが、人々が既存の動作に依存していることを示しており、この動作への変更の結果は必ずしも明白ではありません。

于 2013-02-16T04:35:59.673 に答える
0

ではない正確に。他の回答で提示された理由とは別に、私はそれを指摘したいと思います:

a) Global variables, static local variables are always initialized, if not explicitly, then implicitly zero.
b) For a custom class `class Test`, creating a new instance by `Test *ptr=new Test()` or `Test test;` gives an initialized object.

要約すると、ELFファイルの'.data''.bss'セクションで終わるものは、明示的または暗黙的に(ゼロ)初期化されます。上記の領域にないプリミティブ型の他の変数には、明示的な初期化の前に未定義のコンテンツがあります(コンパイラによって異なります)。これは、ELFファイル自体がa)非常に低コストで変数を現物で初期化する方法を提供する一方で、スタックやヒープなどで変数を初期化することはひどいオーバーヘッドになる可能性があるためです。

初期化にコストがかかる可能性があると主張するclass Objectかもしれません。しかし、何よりも、プリミティブ型の初期化を省略することは、Cでの動作方法であり、したがってC++はそれに準拠します。

于 2013-02-16T05:43:07.463 に答える