ポインタのデータ型が新しく入力されたデータと同じであればエラーにはならないと思いますが、ポインタのデータ型が異なると型の不一致が発生します。私は、コンパイラがそれについて何かをするか (最初にダングリング ポインターを削除するなど)、または単にエラーを与えるかどうか疑問に思っていました。
3 に答える
@YuHaoは絶対に正しいです。
最初にdelete
、プロセスのアドレス空間に以前存在していたページをマップ解除すると、セグメンテーション違反が発生する可能性があります。
それ以外の場合は、どこかにデータを書き込むだけです。あなたがそれをする時までにそこに役立つものがあるかもしれませんが、ないかもしれません. とにかくこれは避けなければなりません。
コンパイラがそれについて何かをするかどうか疑問に思っていました(最初にダングリングポインターを削除するとします)
できました(しません)
または単にエラーを出します。
できました(しません)
ぶら下がりポインタです。それに対する保護はありません。
これは未定義の動作です。これは基本的に答えられません。
おそらく、私たちが同じページにいるので、簡単な概要が役立つでしょう.
Linux のようなマルチタスク OS を搭載した最新の PC を想定してみましょう。
C++ プログラムを実行すると、プライベート メモリ空間を持つプロセスが作成されます。これは、CPU および OS によって RAM 内の実際のアドレスに変換されるアドレスの線形マッピングです。
C++ は、手動でメモリを管理する厳密に型指定された低レベル言語です。強く型付けされているということは、コンパイラがいくつかの基本的なチェックを行って、プログラム内の論理ステートメントが意味を成していることを確認することを意味します。ポインタは単なる別のタイプです。
例えば:
float f = 10.0f; // this is ok, 10.0f is a float literal
float* pF = &f; // types match, & operator returns type float*
int i = f; // types do not match. Compiler error or warning.
int* i = pF; // types do not match, int* is not float*
float f2 = pF; // types do not match, float is not float*
等々。
それはコンパイル時間です。それは本当にそれです。プログラムが実行されると、C++ ランタイムはかなり馬鹿げています。メモリ操作はプログラムの速度を低下させる可能性があり、C++ の哲学は「要求しなかった場合は支払う必要がない」ため、メモリ操作のチェックはあまり行いません。
最も基本的なのは、私たちの記憶は単なる一連のバイトです。float や int などのデータ型はマルチバイト データ型です (32 ビット プラットフォームでは 4 バイト)。つまり、メモリ内の float は、隣接する 4 つのバイト サイズのスロットに格納されます。
最後に、私たちはあなたの質問に答える準備ができています. 実行時にメモリを割り当てるとnew
、使用できるメモリへのポインタが返されます。単一のフロートに対してこれを行うとします。new
そのメモリを「使用中」としてマークする方法を知っています。new
これらの 4 バイトへのポインタを他の人に渡すことはないので、安全です。それを呼び出すdelete
と、メモリがヒープに戻されます-プログラムの他の部分は後で自由に割り当てることができます。しかし、あなたが持っているポインターは変更されていません。ポインターを使用してメモリに書き込むことはできますが、問題が発生するのは今だけです。
例:
float *pF = new float; // allocate 4-bytes on a 32-bit system
*pF = 10.0f; // fine
delete pF; // free the memory
*pF = 20.0f; // ?????
その最後の命令は、「pF が指すメモリに 20.0f を書き込む」と言います。私たちはもはやその記憶を「所有」していません。このポインターは、安全に書き込むことができる有効なメモリを指していないため、ぶら下がっていると言います。ただし、書き込み可能なメモリを指しています。これがバグの原因であることは間違いありません。
メモリが初期化されていないか、以前に削除されたかを示すために特別な値をメモリに書き込む C++ メモリ アロケータがあります。これは、OS とツールセットによって異なります。
このようなバグを見つける別のオプションは、プログラム メモリをシミュレートし、この種のバグにフラグを立てる素晴らしいツールValgrindを使用することです。