2011-01-17 5 views
4

メモリがどのように割り当てられ格納されるかを詳しく調べるために、メモリアドレス空間をスキャンし、値を見つけて新しい値を書き出すアプリケーションを作成しました。アレイはどのようにメモリに格納されていますか?

最終的な目標を持つサンプルアプリケーションを開発しました。これは、プログラムで配列を特定し、新しい配列のシーケンスで上書きすることができるようにしました。この状況では、5つの要素、たとえば

int[] array = new int[] {8,7,6,5,4}; 

私はアプリケーションを実行し、上記の5つの数字のシーケンスを検索しました。私は4と8の間の値を探していたので、合計で5つの数字が並んでいました。残念ながら、配列内の私の連続した数字は、数字の4から8までの何百もの結果と一致しました。特定のシーケンスがメモリ内で隣り合わせに起こることはありませんでした。

メモリ内の数字のセットは、配列を表していて、単に隣り合っている整数ではなく、区別するための方法はありますか?特定の値を見つけたら、それが配列のそれであることを知る方法はありますか?

int[] arrayを宣言すると、配列に存在するものにある種のメタデータを提供する、私の配列の最初のアドレスを指していると思います。

0x123456789 meta-data, 5 - 32 bit integers 
0x123456789 + 32 "8" 
0x123456789 + 64 "7" 
0x123456789 + 96 "6" 
0x123456789 + 128 "5" 
0x123456789 + 160 "4" 

アム私は道オフベース?

+0

Huh? 'int [] array =新しい配列{8,7,6,5,4};'? – Mehrdad

+0

@Lambert oops!一定。 :) –

答えて

4

Debug + Windows + Memory + Memory 1、Addressフィールドを「array」に設定します。あなたは「4バイトの整数」にビューを切り替えるときに、この表示されます:

0x018416BC 6feb2c84 00000005 00000008 00000007 00000006 00000005 00000004 

最初のアドレスがガベージコレクトヒープ内のオブジェクトのアドレス、プラスでのオブジェクトのヘッダの一部であります負のオフセット(syncblkインデックス)。この値を推測することはできません.GCはそれを動かします。 2番目の16進数は、配列型(別名メソッドテーブルポインタ)の '型ハンドル'です。この値を推測することはできません。タイプハンドルは、必要に応じてCLRによって作成されます。 3番目の数字は配列の長さです。残りは配列要素の値です。

デバッガなしで実行時にこの配列を確実に見つけ出す確率はかなり低いです。試してみるのはあまり意味がありません。

+0

+1 - 非常に便利です。私はあなたがVSでそれをすることができるかどうかを決して知らない。 – Aliostad

+0

3番目の数字セットが配列の長さを表し、それが既知の数字と長さのターゲット範囲に一致した後の進行番号 - 私はそれがかなり近づいているのを見ることができます。たとえば、000000FFを検索する場合、255の長さの配列を持っていることを知っていて、次に私が知っていた範囲の先行する255の数字を0-5などの配列にテストしたところ、コードの他の部分はスリムであるように思えます。しかし、それを一致させる可能性は、私が宣言した配列が小さくなる可能性は低くなります。 –

+0

さて、はい。アドレスは4の倍数です。あいまいさが問題です。あなたは「適切な」ものを選択することはありません。検索には20億バイトも要します。 VirtualQueryはこれを減らし、読み込み+書き込みページだけを考慮します。 –

0

Do not。配列はヒープに格納され、ガベージコレクションのために再配置されます。メモリを移動しないようにする必要がある場合は、fixedを使用する必要があります

高性能アレイの後にいる場合は、stackallocを使用し、コード体系を使用してください。

+0

私は、上記のサンプルが宣言されたときにどのように格納されるかを知る以外に、ここでは何もしません。 GC中に配列に何が起こっても、私が求めている範囲外です。教育を探しています。 :) –

0

メモリが常に連続して格納されているとは限りません。それが確実であれば、あなたが求めていることは可能です。

+3

配列は仮想メモリに連続して格納されます。連続仮想メモリは連続した物理メモリを意味するものではありませんが、この「スキャナアプリケーション」が物理アドレスを使用していると非常に驚きます。ハードウェアDMAエンジンを使用してメモリをスキャンする場合は、そのような詳細については心配する必要があります。 –

0

私は正確にはわかりませんが、this articleはあなたの配列へのポインタを得ることができるように思われます。実際のアドレスを決定できると思います。

0

あなたはC#と恐らく.NETを使用していますが、あなたの質問のほとんどはメモリに関する非常に一般的な用語です。最も一般的な意味で、すべてのメモリは、そのメモリが配列、文字列、またはコードを保持しているかどうかにかかわらず、ちょうどビットです。

これを念頭において、現在のプラットフォームのさまざまなデータ型を割り当てる方法の兆候を見つけることができない場合、配列、文​​字列、またはコードを含むメモリに違いはありません。

また、配列内の最初の項目に配列が「ポイントしている」かどうかについても、私は仮定しません。おそらく他の誰かがこの問題に具体的に対処できるかもしれませんが、私は何らかのヘッダーが関係していると思います。

+0

合意。私はC#タグを削除しました。 –

+0

その場合、あなたの質問に対する答えは「いいえ」と言います。 –

関連する問題