4

Jim Trevor の「Cyclone: A safe dialect of C」を PL クラスに使用しながら、C を理解しようとしています。Trevor と彼の共著者は、C の安全なバージョンを作成しようとしているため、言語で初期化されていないポインターを排除しています。ちょっとググって初期化されていないポインターでは、初期化されていないポインターがメモリ内のランダムな場所を指しているように見えます。これだけでは安全ではないようです。初期化されていないポインタを参照すると、メモリの安全でない部分にジャンプします。限目。しかし、トレバーがそれらについて話している方法は、それがより複雑であることを暗示しているようです. 彼は次のコードを引用し、関数 FrmGetObjectIndex が f を逆参照するとき、有効なポインターではなく、予測不可能なアドレス (f のスペースが割り当てられたときにスタック上にあったもの) にアクセスしていると説明しています。

Trevor は、「f のスペースが割り当てられたときにスタックにあったものは何でも」とはどういう意味ですか? 「初期化されていない」ポインタは、デフォルトでメモリ内のランダムな場所に初期化されていますか? または、それらの「ランダムな」動作は、スタックでの予期しない動作のために、これらのポインターに割り当てられたメモリが奇妙な値で満たされる (参照される) ことに関係していますか?

Form *f;
   switch (event->eType) {
   case frmOpenEvent:
   f = FrmGetActiveForm(); ...
   case ctlSelectEvent:
   i = FrmGetObjectIndex(f, field); ...
}
4

2 に答える 2

5

Trevor は、「f のスペースが割り当てられたときにスタックにあったものは何でも」とはどういう意味ですか?

彼は、ほとんどのアセンブリ言語では、スタック上のスペースを予約し、新しく予約されたスペース内に初期値を書き込むために別々の命令が使用されることを意味します。C プログラムが初期化されていない変数を使用する場合、プログラムは通常、実行時にスタック スペースを予約する命令を実行しますが、それを設定する命令は実行しません。ポインターを使用すると、スペースが予約される前にスタック上にあったビット パターンが文字どおり含まれます。良い場合、これは無効なアドレスになります。悪いケースでは、これはたまたま有効なアドレスであり、その影響は予測できません。

これは典型的な動作です。理論的な観点からは、不確定な値を使用することは未定義の動作です。単に無効なアドレスや有効なアドレスにアクセスするだけでなく、はるかに奇妙なことが発生する可能性があります (初期化されていないデータ (アドレスではない) が誤ってまたは意図的に使用された例)。


Cyclone などの C の制限されたサブセットが防止しようとしている種類の危険を次に示します。

int a, *p;

int main(int c, char **v){
  int l, *lp, i;
  if (c & 1) 
    a = l + 1;      // danger
  if (c & 2)
    *lp = 3;        // danger
  if (c & 4)
    {
      p = &a;  
      for (i=0; i<=1; i++)
        {
          int block_local;
          *p = 4;   // danger
          p = &block_local;
        }
    }
}

最後の危険な行では、実際には 4 が variable に書き込まれる可能性が最も高いですblock_localが、実際には 2 回目の反復でpは不確定であり、プログラムは にアクセスすることは想定されておらず、アクセス*pした場合の動作は未定義です。

于 2012-11-12T16:58:53.480 に答える
1

最新の OS では、コア ダンプが危険です。メモリ管理のない以前のシステムでは、外部ハードウェアへのメモリ マップ I/O の可能性があり、危険度はまったく異なります。

于 2012-11-12T17:51:30.537 に答える