私はC++を学んでいて、初期化されていないままにしておくと、ポインターがメモリ内のランダムな場所をポイントし、メモリが他のプログラムで使用される可能性があるという問題が発生する可能性があることを知りました。
この場合、コードのどの部分にもこの行を含めないでください。
int* ptr;
代わりに、次のようなものが必要です
int* ptr = NULL; //Is this going to avoid the problem
最初の行を見たので提案してください(int* ptr;
)多くの本でこの疑問を抱いています。可能であれば、いくつかの例も挙げてください。
int* ptr = NULL; //Is this going to avoid the problem
これにより、ptr
がNULL
を指すようになり、デフォルト/初期化されていない値として明示的に確認できます。それはあなたが説明する問題を防ぎますが、不注意なプログラマーがチェックせずに誤ってnullポインターを逆参照する可能性があり、未定義の動作を引き起こします。
主な利点は、ptr
が何かに初期化されているかどうかを確認できることです。つまり、
if (ptr != NULL)
{
// assume it points to something
}
これはかなり慣用的であるため、NULL
へのポインタを初期化しないことはかなり危険です。ポインタは、実際には何も指し示さないNULL以外のガベージ値に初期化されます。最悪の場合、上記のチェックはパスし、ポインタのアドレスが合法的にアクセスできるメモリである場合に、さらに悪い問題を引き起こします。一部の組み込み環境では、メモリの任意の部分にアクセスできる場合があるため、メモリのランダムな部分または実行中のコードのランダムな部分を誤って破損する可能性があります。
常に変数を初期化します。
場合によっては、NULL
に初期化する必要があるかもしれませんが、ほとんどの場合、ポインタを初期化できるはずです保持するはずの値へ。変数をできるだけ遅く宣言し、コードの15行下ではなく、その時点で変数を初期化します。
この線:
int* ptr;
ポインタ値を特定のものに初期化することは、絶対に保証されていません。この線:
int* ptr = NULL;
アドレス0を指すようにポインターを初期化します。これは実際には有用なものを一切保持せず、従来は無効なポインター値としてチェックされます。
もちろん、Doug T.が言ったように、このポインタをチェックせずに使用しようとすることは依然として可能であり、そのためまったく同じようにクラッシュします。
NULLに明示的に初期化することには、ポインタを有用なものに設定する前にポインタを逆参照するとクラッシュするという利点があります。これは、深刻なバグを隠しながらコードが「誤って」機能するのを防ぐためです。
宣言の発生中に何らかの理由でポインターを初期化できない場合は、ポインターをNULLに初期化することをお勧めします。例えば:
Object *ptr = new Object();
通常、関数はポインターの値をNULLに対してチェックして、ポインターが以前に初期化されたことを確認できます。明示的にNULLに設定しておらず、ランダムな値を指している場合、逆参照される可能性があり、segfaultが発生します。
ポインターが使用されない場合、コンパイラーはそれを単に無視します。それをNULLに初期化するのは安全です。
関数宣言と混同しないでよろしいですか?関数が次のように宣言されることは非常に一般的です
char * do_something(const char * one、const char * two);
この場合、ポインタを使用して、渡す引数の種類を指定します。
安全のために設計されていないという点で、C++はCに続きます。それは効率的であるように設計されています。したがって、自動変数が初期化されないのはこのためです。初期化する前にポインターを使用しないようにするのはあなた次第です(ただし、変数を初期化しないと多くのコンパイラーが警告を出します)。
int a,*ptr;
今
print(ptr,*ptr)
上記のコードでは、2つのケースが考えられます。
Ptrのデフォルト値がプログラムの使用済みメモリのアドレスでない場合に実行されます。
出力:
ptr *ptr
eg. 0x400730 -1992206795
Ptrのデフォルトアドレスがプログラムの使用済みメモリのアドレスである場合は、エラー(セグメントエラー)になります。例えば。メモリ内の変数aのアドレスも0x400730の場合。