2012-08-06 10 views
6

C/C++変数に私が使用できるポインタがあります。この変数が属するメモリのどのセグメントを正確に作ることは可能ですか?はいの場合、どうですか?アドレスがヒープまたはスタックまたはレジスタに属しているかどうかを確認する

注:変数等グローバル/ローカルの場合、私はちょうどこの変数のアドレス、それ以上の情報を持って

+8

ない可能、少なくともではない移植可能な方法であると言います。 – juanchopanza

+3

あなたはどのような問題を解決しようとしていますか?ランタイムまたはコンパイル時のソリューションが必要ですか?レジスタにはアドレスがありません。 –

+0

グローバル変数がスタックかヒープに属しているかどうかの議論がありました。自分自身を確認したかったのです。P –

答えて

2

あなたのアーキテクチャでは、あなたのヒープへのポインタを持っているか、地域を積み重ねるかどうかを確認します。通常、いくつかのスタックポインタまたはフレームポインタがあります。

次に、実際のアドレスをそれらのアドレスと比較して、それらの所属を決定します。

+0

hehe、そうですね;)しかし、エキゾチックなアーキテクチャについて言えば、グローバル変数をスタックやヒープに置くこともできます。これはアーキテクチャにも依存します。 – duedl0r

+0

Univacハードウェアにスタックがないと言いましたか? .-) –

+0

私は1981年以降に発明されたものを信じています。D – duedl0r

1

まず、実行可能ファイル内のさまざまなセクションの開始点と終了点を特定できます。このためには、最終的には、このように各セクションの周りにリンカスクリプトでいくつかの変数を追加する必要があります。

SECTIONS { 
    [...] 
    .data : { 
     data_start = .; 
     *(.data) 
     data_end = .; 
    } 
    [...] 
} 

あなたは、あなたのC/C++コードで外部としてこれらの変数を宣言すると、アドレスを比較するために、それらを直接使用することができます識別したい

リンカースクリプトを微調整するのは簡単ではないかもしれません。 gccで、あなたがそれをダンプすることができます。その後、

gcc -Wl,-verbose whatever.c 

すでに(汚い)出力で定義された変数を探してみてください。

スタックの境界を取得するには、main()関数の先頭にダミー変数をインスタンス化し、そのアドレスをスタックの先頭として保存し、現在の位置に別のインスタンスをインスタンス化します。あなたに底を与えてください。ただし、コンパイラはCの変数のスタック順序は保証されておらず、スタックの使用も保証されていないので、このように正しく動作しない可能性があるので注意してください。

最後に、ヒープの場合、私はトリックを持っていません。私はちょうど推測することはできませんデータ/ bssのではない/誘導体とスタックではないヒープ(レジスタを除くが、あなたがアドレスを得ることができる場合は、私はコンパイラは、 )。

2

あなたは、Linux(他のUnixわからない)を使用している場合は、ファイルに/proc/<pid>/maps

0

を情報を見つけることができるかもしれない、それはあなたの状況に合った場合、私は正確に知りませんが、あなたは試すことができますobjdump -t elfファイルのシンボルテーブルを参照してください。必要なのは、変数のアドレスだけです。そこには、各変数のセクションを示すフラグがあります。詳細は、マニュアルページobjdumpを参照してください。

出力例:

0804a020 g  O .bss 00000004    var 

それはvarがアドレス0804a020gローバルO bject、セクション.bss