0

私は自分のプログラムでポインターをますます使用しており、ポインターについて読んでいる間、私が見つけたすべてのガイドまたはチュートリアルは、ポインターの誤った使用が「悲惨な」結果をもたらす可能性があると述べました。

さて、いくつかの大きなメモリリークが発生し、ポインタが間違ったポインタ変数を逆参照して間違った値を返したことがありますが、それ以外は「悲惨な」ことはありません。私のコンピュータや他のプログラムがクラッシュするように。

誰かが私に簡単なコード例を教えてもらえますか?それは間違いなく「悲惨な」結果をもたらします。おそらく、そのコードを誤って使用したことがある場合に備えて、何が起こったのかについての裏話がありますか?「悲惨な」結果とは、他のプログラムやOSに干渉し、クラッシュする可能性のあるコードを意味します。

4

4 に答える 4

3

災害には主に2種類あります。ダングリングポインタとメモリリークです。

ダングリングポインタは、ポインタがオブジェクトのアドレスではないアドレスを格納する場合です。

T* first;
T* second; //somewhere in another piece of code
first = new T();
second = first;
delete first;
first = 0; //second still stores the address of an already deleted object

メモリリークは、ヒープに割り当てられたオブジェクトのアドレスを格納するポインタがない場合です。

T* object;
for( int i = 0; i < 10; i++ ) {
  object = new T();
}
delete object; // now the first nine objects are unreacheable

ダングリングポインタを使用すると、未定義の動作が発生するため、ダングリングポインタは不適切です。プログラムがクラッシュしたり、無関係なデータを変更したりする可能性があり、これにより後で問題が発生します。割り当てられたメモリは再利用できず、プログラムはしばらくしてメモリが不足する可能性があるため、メモリリークはひどいものです。

于 2010-12-22T10:54:15.577 に答える
3

ポインタ演算が正しくないと、障害が発生する可能性もあります。境界を間違えるとバッファオーバーフローが発生し、バッファオーバーフローによってデータが破損するためです。たとえば、スタックスマッシングは次のようになります。

void test_fun(int i)
    int x[5];
    for (int *p = x; p < x+10; ++p) { // obvious error, some are more subtle
        *p = i;
    }
    return; // execution may resume at address `i`, with entertaining results
}

もちろん、strcpyまたはmemcpy[*]を呼び出すだけで同じ間違いを犯す可能性があります。自分でポインタ演算を行う必要はありません。攻撃者がの値を制御する場合i(おそらく、入力ファイルから読み取られ、攻撃者が悪意のあるファイルを作成するため)、手にクラッシュするよりも悪い結果になる可能性があります。iよりプラットフォーム固有のトリックと組み合わせて、攻撃者は、に戻ると最終的に攻撃者から提供されたコードを実行するように調整できる可能性があります。

[*]またはstrncpy、またはstrlcpy、またはstrcpy_s、、、、std::copy誰かが始める前に。どういうわけか境界が間違っていると、その間違った境界を境界チェック関数に提供することはまだ間違っています...

于 2010-12-22T11:09:54.777 に答える
0

私が見た中で最も厄介なのは「遅延障害」です。誤って行われた書き込みアクセスは、後でのみ使用されるデータ構造に損傷を与え、完全に無関係なコードの誤った出力を生成します。デバッグ中に、「マシンの台頭」を観察します。データ構造は、プログラマーの意向に反して、割り当てられたことのない間違った値を不思議に取得します。実際の場所から数千LOC離れた場所でエラーを検索している可能性があります。

于 2013-02-18T18:55:29.227 に答える
0

いくつかのケースが思い浮かびます:

  • スコープを離れた後も、free()/ delete()dメモリまたはローカル変数にアクセスし続けます
  • 所有権が不明なためにヒープメモリがリークしている
  • データへの意図しない共有アクセス。ポイントされた値への変更により、それらで動作するアルゴリズムの一部が混乱する可能性があります
    • 偶然の浅いコピー
  • 他のデータへのポインタを実際に含む想定PODデータのナイーブなバイナリ書き込みによる不完全/欠陥のあるシリアル化
  • 共有メモリ内の安全でないデータをマルチプロセスします。ポインタ(特に仮想ディスパッチポインタ)は、それにアクセスするプロセスごとに異なる必要があります。
  • コードがループで無期限にスタックする原因となる循環データリンケージ
  • 誤ってデータの外に移動するような方法でポインタをデータ内で移動する(問題は配列インデックスに似ていますが、必ずしも一定の参照と一貫して安全な相対インデックス範囲がないため、より複雑です)
  • 番兵の値を正しくチェック/処理できない
  • ポインタが指すデータのタイプに関する問題
    • 安全でない/誤ったキャストの使用(例:動的キャストが必要な場合のキャストの再解釈)
    • ポインタからのインデックス付けがポインタから型へのサイズの単位で行われることを理解できない
    • ポインタから短い整数型への/からの無効な変換
于 2010-12-22T11:14:23.327 に答える