• ベストアンサー

論理アドレスの割り当て方法

現在、どのようにプログラムが実行されているかについて調べているのですが、Cプログラムをコンパイルする際に、変数に対してどのように論理アドレス(再配置可能アドレス)は割り当てられるのでしょうか?自分としては、変数の宣言された順に割り当てられるのかなぁと思っているのですが、実際どうなのかがわかりません。お願いします。教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
  • neKo_deux
  • ベストアンサー率44% (5541/12319)
回答No.1

> 変数に対してどのように論理アドレス(再配置可能アドレス)は割り当てられるのでしょうか? OSなどの処理系ごとに異なります。 main() { int a,b,c; printf("&a=%p, &b=%p, &c=%p\n", &a, &b, &c); } などのプログラムを作成して調べてみては? 変数の宣言を、グローバル、static、レジスタ(?)などと変えてみても面白いと思います。 -- Intel系ですと、スタックの末尾から宣言した順に前向きに…だったと思います。 何かの間違いで大量のメモリを確保してしまった場合、前向きに確保して行けば、前方にあるプログラム領域に到達して、メモリ破壊してプログラムが停止するので、他のメモリ領域に影響を与えないというような説明を聞いた事があります。ちょっと眉唾ですが。

その他の回答 (1)

  • khurata
  • ベストアンサー率40% (54/134)
回答No.2

 リンケージまで終了した段階のアドレスであるならば、#1の回答でよろしいかと存じます。  もし、コンパイル後リンク前のオブジェクトの段階(再配置可能)でのアドレスを知りたいならば、マップリストを出力するオプションを付けてコンパイルすれば、各変数や関数のリロケータブルなメモリマップが得られます。  また、リンク後のプログラムについて知るなら、#1の回答の他に、リンクマップを出力するオプションを用いたり、アセンブリ言語で出力するオプションを用いるという方法もあります。  コンパイルオプションについては処理系依存ですので、ご使用の処理系について調べて頂ければ、と思います。

関連するQ&A

  • DLLはアドレスを共有する?

     CでWindowsプログラミングの勉強をしています.そこでDLLについての質問なのですが,ある本で「DLLは複数のプログラムが共有し,ひとつのDLLはひとつしかメモリ上に配置されない」という文章を読みました.プログラムはDLLの配置されてあるアドレスを元に,DLL内の関数を実行するのだと考えれば納得はいきましたが,よく考えたらおかしいと思いました.  それは「変数,関数」の取り扱いはどうなるのか,ということです.C言語で物理メモリアドレスを見る方法がわからないので何とも言えませんが,試しに,DLL内に次のような関数MyFunctionを用意し,このDLLを取り込むプログラムを同時に2つ走らせ,MyFunctionを何度も呼んでDll1_Variableの値を増加させていきました. LIBSPEC int MyFunction(LPCWSTR str) { static int Dll1_Variable=0; Dll1_Variable++; _tprintf(_T("%d\n"),Dll1_Variable); return 0; }  もしDLLが共有されているのならば,Dll1_Variableの値は2つのプログラムから同時に更新されると思うのですが,実際には2つのプログラム上でまったく独立(つまり各プログラムごとに1,2,3,...というように)増加していきました.こうなるとDLLって本当に共有されているのかという,不信感が出てきてしまいます.  なんだか重大な勘違いをしている気がしてなりませんが,上記のプログラムがなぜ独立に変数が増加していくのか,「DLLが共有される」というのは実際にはどういう仕組みになっているのか,ご存知の方がいらっしゃったらご教授ください.わかりにくい質問ですみません.よろしくお願いします.

  • OSがプログラムをどのように実行させているか

    現在、OSはどのようにプログラムを実行させるのかを調べています。Cプログラムを作り、そのCプログラムをコンパイルして生成されたexeファイルを実行させますが、この際に、OSはどのような事を行っているのでしょうか?概要でいいので、プログラムを実行させる際にOSの行っていることを教えてください。お願いします。

  • 配列と他の変数のメモリ領域重複の問題について質問

    dsPICで配列を使用する際、他の変数もその配列の存在するメモリ領域に配置されてしまいます。 プログラムにはC言語を用いています。環境は「MPLAB C30 v3.31」、「MPLAB LINK30 v3.31」「MPLAB v8.85」です。 状況としてはunsigned char型で要素数320の配列をグローバル宣言します。そしてmain関数やその他の関数内でローカル変数を宣言するとその変数が配列の中に存在することになってしまうというものです。色々試したところ、そのローカル変数をstaticで宣言するとそのような症状は出なくなりました。 この現象には、初期化をする関数内でカウンタとしてローカル変数を宣言し、for文で配列を0でクリアさせようとしたところ、MPLABSIMでデバッグすると永久ループしたことから気づきました。Watchを用いて確認したところ配列の中にそのカウンタ変数が配置されていたため最終的に自分自身を0でクリアしてしまうことで永久ループしてしまうことがわかりました。 なぜこうなるのかよくわかりません。この配列以外にはおおきな領域を必要とする変数は宣言していませんのでData memoryの容量的な問題ではないと思っています。staticで宣言すれば何とかなりますが、これでは無駄なメモリを消費してしまいます。また、絶対アドレス指定をする方法もありますが、「ignoring address attribute applied to automatic 変数名」というwarningがでて結局出来ませんでした。 。 このような現象を起こさせない様にするため,、確実にメモリを確保するためにはどうすればよいのでしょうか。 この問題のために先に進めず、大変困っております。どうかご教授ください。 もう一つ、変数の生存期間について質問なのですが、ある関数内で宣言したローカル変数をカウンタとして使い、指定の回数だけ他の関数を繰り返し実行する場合、他の関数に飛んだ時もそのローカル変数は確実に生存しているのでしょうか。重ねてお願いします。 不足がございましたら補足しますのでお教え下さい。

  • アドレスの計算が合わない

    C++でポインタの勉強をしています。 その中でアドレスについての以下のような記述がありました。 <例1> struct { int a; int b; int c; } oshiete; cout << &oshiete.a << endl; cout << &oshiete.b << endl; cout << &oshiete.c << endl; このように、構造体の中で宣言された変数の領域は連続した場所を確保するというものでした。これの実行結果は以下の様になりました。 0013FF5C 0013FF60 0013FF64 int型のバイト数は4でしたので、それぞれの変数の先頭アドレスは4つ間隔になっています。しかし、これの2つ目の変数bをshort型に変えても同じ結果が返ってくるのです。short型のバイト数は2です。 <例2> struct { int a; short b; int c; } oshiete; cout << &oshiete.a << endl; cout << &oshiete.b << endl; cout << &oshiete.c << endl; 結果: 0013FF5C 0013FF60 0013FF64 そして変数aもshort型にすると、やっと納得のいく結果になりました。 <例3> struct { short a; short b; int c; } oshiete; cout << &oshiete.a << endl; cout << &oshiete.b << endl; cout << &oshiete.c << endl; 結果: 0013FF60 0013FF62 0013FF64 なぜ<例2>ではint, short, intの順で宣言したのにアドレスが全て4つ間隔なのでしょうか?例えば先頭アドレスが0013FF5Cであるなら、 0013FF5C 0013FF60 0013FF62 のように1つ目と2つ目のアドレス差は4、2つ目と3つ目のアドレス差は2になるはずだと思うのですが。

  • Borland C++ Compiler について…

    こんにちは。 Borland C++ Compiler 5.5 をダウンロードして、 メモ帳で、プログラムを書き (一番最初にたいていの人が書く例のアレ。) コマンドプロンプトでコンパイル…。 できません。どうしてでしょう?というのが質問です。 もちろん環境変数は設定しました。 変数名 > path 変数値 > C:\Borland\bcc55\bin このように。 実際にコンパイルすると 'bcc32' は、内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチ ファイルとして認識されていません。 と警告が出ます。 さらに、直接 C:\borland\bcc55\Bin\bcc32 と入力すると、コンパイルしてくれるようです。 が、ここでも別のエラーがでます。 エラー E2133: コマンド 'ilink32.exe' を実行できない と。 まとめ 1.コンパイルができない(環境変数関係?) 2.ilink32.exe が実行できない 以上の2点について、解決策をご存知の方がおられましたら、 ご教授願いたく存じます。

  • VC2005(x86系)の実行アドレス取得方法について

    VC2005(x86系)において、現在実行中のRAMアドレス(プログラムカウンタ) を取得したいのですが、どのようにすれば良いでしょうか。 【やってみたこと】 下記のようにすれば出来るかと思ったのですが、 コンパイルエラーでした...。 (eipが使えないとのこと) -------- void main() { unsigned long pc_pos; __asm { mov pc_pos, eip } ・ ・ ・ } -------- 特にアセンブリでやりたいとかの指定はございません。 ただ、実行しているプログラムカウンタ位置を取得する 方法がございましたら、ご教授願えませんでしょうか。

  • C言語のStatic変数について

    現在、C言語の勉強しながらゲームプログラムにチャレンジしています。 二つの関数で利用する変数を作りたかったので、Static宣言された変数を容易しました。 ですが、この変数、一度処理が終わると当面使わない変数なのです。 (ただし、処理途中は何度も呼び出されるので値は保持しなければいけません) よって、メモリ上に延々居座られるのが邪魔に思えて仕方ありません。 実際、大したことないだろうとは思うのですが。 このStaticで宣言された変数を、自分の好きなタイミングでメモリ上から解放するような処理はできませんか? もしくはメモリ上に居座ることのない処理の仕方などありましたら、 考え方を教えていただけるとうれしいです。よろしくお願いします。

  • C言語での変数宣言の場所

    今まで2年ほどJavaを使っていましたが、最近になってCを使う必要が出てきました。Cは大学の頃に授業で学んだ程度のレベルです。 それはさておき。 JavaやC++ではメソッド内のどの場所ででも、新たな変数を宣言して使用できますが、Cでは関数内の最初の方でしか宣言できないですよね? 先日、その事を意識せずに、Javaと同じように変数を関数の任意の場所で宣言しているようなCのソースを書き、gccでコンパイルしたところ、コンパイルが通ってしまいました。 その時のファイルは「.c」ファイルです。 このソースはC++のソースとして、コンパイラが認識してしまったのでしょうか?拡張子が「.cpp」ではなく「.c」のままでしたが、コンパイラは拡張子ではなく、ソースを読み込んでから、そのプログラムがCなのかC++なのか判断しているのでしょうか? いまいちピンと来ないので、どなたか解説お願いします。

  • 配列を作った場合は、その結果は何に反映されるのですか?

    Linux上でC言語のプログラムを作るとして。。。 例えば unsigned char hoge[10]; という変数を宣言した場合と unsigned char hoge[]20]; という変数を宣言した場合とでは 生成モジュールのバイトすうは10バイトちがうのでしょうか? 配列を宣言した場合には、コンパイル時に領域確保されるとどこかのHPで見た記憶があるのですが、それが正しければ上に書いたように生成モジュールのバイト数が10バイト変るのかな・・・ また、その生成モジュールを実行した場合の使用メモリ量は(top,vmstat等で監視した場合)は、そういう差ってでてくるのでしょうか? 宜しくお願いいたします。

  • C# 変数の動的な再定義

    こんにちわ  変数の動的な再定義というものが可能かどうかお伺いしたく質問させていただきました。 具体的には宣言時にはpublic int numberと宣言しておいて、プログラムのLoad時に、プログラム内でdouble型で宣言しなおすといった内容です。 ※上記の内容は質問用のサンプルです。ジェネリックを使えばいいとかあると思いますがあくまで可能かどうかの質問です。 やりたいことは、プログラム実行時に型を決めて、コンパイルも通したいという内容です。 dynamicを使用すれば想定通りの動きのものはできましたが、別のやり方も模索しております。 プログラム内でなんとか再定義ができないものかと思ってます。

専門家に質問してみよう