メモリのセクションに関する質問

このQ&Aのポイント
  • グローバル変数のメモリ配置について質問があります。
  • スタックとヒープのセクションについて認識を確認したいです。
  • 変数名やアドレスを使用してセクションを確認する方法を知りたいです。
回答を見る
  • ベストアンサー

メモリのセクションに関して

こんばんは。 表題の通り、セクション領域に関して3点ほどご質問が御座います。 (1)グローバル変数は、  ・0でない初期化を行う→.dataセクション  ・0で初期化、または、初期化なし→.bssセクション  上記のようにメモリに配置されると思いますが、  上記をstatic宣言した場合でも結果は同じでしょうか?  (static宣言したグローバル変数) (2)スタック、ヒープそれぞれが属するセクションは、それぞれ専用の  スタックセクション、ヒープセクションという名のセクションがあるという認識であっていますでしょうか?  (.dataでもなく、.bssでもなく、.textでもなく、.rodataでもなく。。。) (3)プログラム中に宣言した変数名や、そのアドレスを使用して、属しているセクションを確認することが出来る方法はありますでしょうか? どうかご教授をお願い致します。

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

  • ベストアンサー
回答No.2

> (1)グローバル変数は、 > 上記をstatic宣言した場合でも結果は同じでしょうか? > (static宣言したグローバル変数) 静的グローバル変数はシンボルの公開が抑止されるのみでその他に違いはない場合が多いかと。 > (2)スタック、ヒープそれぞれが属するセクションは、それぞれ専用の > スタックセクション、ヒープセクションという名のセクションがあるという認識であっていますでしょうか? ありません。 > (3)プログラム中に宣言した変数名や、そのアドレスを使用して、属しているセクションを確認することが出来る方法はありますでしょうか? 通常、各アドレスはまとまっている(例えば1000-2999はtextで3000-3999はbss,4000-5999はdataの様に)のでアドレスを調べれば解ります。 実行ファイルの形式上情報がありますので実行ファイルを解析すれば各セクションの位置や大きさはわかります。(詳しく知りたい場合にはunix系のsizeコマンドのソースを参照するのも良いかと) elf形式やaout形式にマニュアルページやヘッダなども知る上で良い資料となりそうに思います。 ※javaやC++には固有のセクションが追加されている場合があったり。 > (3)プログラム中に宣言した変数名や、そのアドレスを使用して、属しているセクションを確認することが出来る方法はありますでしょうか? 通常、アドレスを調べれば解ります。 予約された領域を除き残った領域を下位アドレスからヒープとして、上位アドレスからスタックとして動的割り当てしたりするのではないかな。

null_null
質問者

お礼

ご回答有難う御座いました。

その他の回答 (2)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

「一般的」ってどういうこと? この辺は規格では一切触れられていない話であり, 処理系ごとに違ってよいということは十分理解していて当然ですよね.

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

何か特定の処理系を想定しているように見えるので, その処理系でやってみればわかるんじゃないの?

null_null
質問者

お礼

ご回答ありがとうございます。 >何か特定の処理系を想定しているように見えるので,  →いえ、こちらはあくまで一般的な事例をご教授いただけたらと思っています。 >その処理系でやってみればわかるんじゃないの?  →質問(3)の通り確認の仕方が不明です。

関連するQ&A

  • VB.NETのメモリ領域について

    VB.NETのメモリ領域について 以下の(1)~(12)の変数のために、 スタック領域、静的領域、ヒープ領域のどこのメモリが使われるか教えてください。 Class Sample   Dim a As Integer '(1)   Dim b As String = "BBB" '(2)   Shared c As Integer '(3)   Shared d As String = "DDD" '(4)   Sub X()     Dim f As Integer '(5)     Dim g As String = "GGG" '(6)     Static h As Integer '(7)     Static i As String = "III" '(8)   End Sub   Shared Sub Y()     Dim k As Integer '(9)     Dim l As String = "LLL" '(10)     Static m As Integer '(11)     Static n As String = "NNN" '(12)   End Sub End Class それぞれこんな認識で合ってますか? スタック領域 (1)(5)(9) スタック領域にポインタ+ヒープ領域に実体 (2)(6)(10) 静的領域 (3)(7)(11) 静的領域にポインタ+ヒープ領域に実体 (4)(8)(12)

  • H8 マイコン セクションの設定について

    最近H8/3694Fを使ってマイコンの勉強をしております。 HEWを使ってコンパイルするときのセクションの設定に ついて質問があります。 プログラム・セクションの設定を一通り終え、ビルドすると 「L2321 (E) section "S" overlaps sction "P"」 とエラーメッセージが出てしまいました。 色々調べてみるとSはスタック領域、Pはプログラム領域 でこれに重なりができてしまっているようなのですが、 これ以上どうしてよいのかわからず困っています。 おそらくセクション設定を変更すればよいと思っていますが プログラム領域にどれくらい、スタック領域にどれくらい を配置すればいいというのはどうやって求めればよいのでしょう? HEWのメモリマップを表示させて見る方法があるようですが 見てもいまいちわかりませんでした。 使用環境:OS:WindowsXP、HEW4.04.01.001 以上、追記補足いたします。詳しい方教えていただけないでしょうか

  • スタックメモリについて

    プログラムの起動時に、スタックメモリは初期化(NULLに設定)されるのでしょうか。 PUSH・POPで使用したらデータは残りますが、未使用の場合、初期化されているかの質問です。 グローバル変数の領域はクリアされると思われますが、スタックは不明です。 クリアされないときは、ほかのプログラムで使用されたゴミデータが 残っているのでしょうか 目的は、スタック領域でメモリ障害の場合動作が変わってしまうのか、確認したいためです。 すいませんが、よろしくお願いします。

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

    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がでて結局出来ませんでした。 。 このような現象を起こさせない様にするため,、確実にメモリを確保するためにはどうすればよいのでしょうか。 この問題のために先に進めず、大変困っております。どうかご教授ください。 もう一つ、変数の生存期間について質問なのですが、ある関数内で宣言したローカル変数をカウンタとして使い、指定の回数だけ他の関数を繰り返し実行する場合、他の関数に飛んだ時もそのローカル変数は確実に生存しているのでしょうか。重ねてお願いします。 不足がございましたら補足しますのでお教え下さい。

  • H8マイコンのメモリセクションの変更を行いたい

    以前私はこのような質問をこのサイトでさせて頂きました。 HEWのビルドで出てきたビルドエラーについて#8678205 #okwave #q8678205 http://okwave.jp/qa/q8678205.html この質問の中で (エラー内容) ** L2321 (E) Section "S" overlaps section "R" Optimizing Linkage Editor Abort ERROR: Process failed with return code: 1 このエラー内容が、Rセクション(初期化領域)の容量がSセクション(スタック領域)にオーバーしているということがわかり、Rセクションの容量を減らすからSセクションの容量を減らして、Rセクションに割り当てる解決方というのを知りました。 実際に開発環境のHEWのtoolchainのセクション設定の項目で変更してビルドが完了し、mapファイルでも設定した通りのアドレスにセクションが設定できることを確認しました。 そのため、初期ではSセクションのスタックは0x200(512)Byteだったのですが、0x1E0(480)Byteと小さくしてしまったのですが、スタック領域を小さくするというのは少し不安を感じています。 他にRAM領域がないかを確認したところ、H8/2368マイコンの外部にCYPRESS社製のSRAM CY62148EV30LL-45ZSX1 TSOPII(32P3Y-H) 512kbyteのメモリをアドレス0x600000番地スタートで接続していることがわかりました。 512kbyteも容量があり、Rセクションはマップで見ても3.2kbyte程度なので、Rセクションだけこのメモリ領域に移したいと考えています。 ただ、 元々このメモリには次のようなメモリセクションが設定されています。 0x00600000 , BHEAPMEM 0x00670000 , BJURNEL このBHEAPMEMとBJURNELという文字をソースコード内で検索してみても全く使用されていない文字で検索できませんでした。 ソースコード内の0x600000番地についての記述では次のような (memmap.h) #define SRAM_BASE_ADDR 0x600000 /* size 512 K Byte (0x80000) */ #define SRAM_BASE 0x600000 /* size 512 K Byte (0x80000) */ (task.c) void * my_malloc(size_t size) { void * p; OS_ENTER_CRITICAL(); p = (void *)malloc(size); if(p == NULL || ((u32)p < (u32)SRAM_BASE_ADDR || (u32)p > ((u32)SRAM_BASE_ADDR + (u32)0x800000))) { printf("malloc error\n\r"); task_reset(); } OS_EXIT_CRITICAL(); return (void *)p; } 現在のメモリセクションマップはこのようになっています。 Address section 0x00000400 , PResetPRG,PintPRG 0x00000800 , P,C,C$DSEC,C$BSEC,D 0x00600000 , BHEAPMEM 0x00670000 , BJURNEL 0x00FF4000 , BPROGERASE 0x00FF4000 , B,R 0x00FFBE00 , S これを、次のように変えたいと思っています。 Address section 0x00000400 , PResetPRG,PintPRG 0x00000800 , P,C,C$DSEC,C$BSEC,D 0x00600000 , BHEAPMEM 0x0066F000 , R 0x00670000 , BJURNEL 0x00FF4000 , BPROGERASE 0x00FF4000 , B 0x00FFBE00 , S 実際にこのようなメモリセクションに変更することは可能なのか、また、実際に変更した場合にBHEAPMEM領域に問題が起きないかとか他に調べなければならないことなど、ご教示頂きますよう、どうぞよろしくお願い致します。

  • C++ の new演算子について

    C++ の new演算子について質問です。 new演算子を用いてクラスのインスタンスを作ったときに、 クラスのメンバー関数内で使用される自動変数はメモリの何処に割り付けられますか? 以下の回答の内のいずれかと想定しています。 ・ヒープ領域 ・スタック領域 たとえば、以下のように、クラスTestClassが定義されていたとします。 class TestClass { int x; // int型(4byteとする) char y; // char型(1byte) long z; // long型(4byte) void play(short); } void main(void){ TestClass* pt = new a(); play(10); } void TestClass:: play(short n){ char a; long b; static c; for(int a = 0; a < 10; a++ ){ b = n * a; cout << b; } } main関数内で、インスタンスを作成した時点で ・TestClassのデータメンバx,y,z ⇒ ヒープ領域に確保(4+1+4 = 9byte。もしかしたらアライメント     の関係で もう少し大きく領域を確保するかも) ・play関数で使われる変数n,a,bの領域は何処に確保されるのでしょうか? 変数cは静的変数用領域に保存される? new演算子で作ったインスタンスはdelete演算子を使わないと消えないと勉強しました。(OSが消さない限り) つまり、上記ではmain関数を抜けても、変数x,y,z,n,a,bの実体は残ると考えてよいのでしょうか? そう考えると、n,a,bの実体はスタックではなく、ヒープ領域に確保する気がします、、 どうか、ご教授ください。

  • データ・BSS セグメントが分かれている理由

    実行可能プログラムのデータ領域に データセグメントと BSS セグメントがありますが、 初期値が設定されているかどうかでこれら 2 つを分ける理由がいまいちわからず悩んでいます。 下記ページを見ると、 「初期値のある変数の場合、初期値を実行ファイルに書き込んでおく必要があるのに対し、 初期値のない変数は実行ファイルに書き込んでおく必要がない」 と書かれているのですが、どうも 「初期値のない変数は実行ファイルに書き込んでおく必要がない」 についてよくわかっていません。 どなたか補足いただけると嬉しいです。よろしくお願いします block started by symbol - 辞書にない英語 - livedoor Wiki(ウィキ) http://wiki.livedoor.jp/yushinhozumi/d/block%20started%20by%20symbol .bss - Wikipedia http://ja.wikipedia.org/wiki/.bss

  • C++で、メンバもヒープに確保されていますか

    C++でどこまでヒープに確保されるのかが分からなくなる場合があります。 特に、配列がある場合や、クラスを使う場合newしてインスタンス作って使用する場合と、 そうでない場合があり、どこまでヒープ領域に確保されているのか 分からなくなってしまっています。 (開発環境 Visual Studio 2013等) Q1 クラス内の配列 class AA{ public: int x; int dat[10]; }; AA *a0 = new AA(); とする場合と AA a1; とする場合。 このとき、メンバ変数はそれぞれ、 a0->xはヒープ領域に確保 a1.xはスタック領域に確保 されるという理解で良いですか? そして、配列a0->dat[0]等 もヒープ領域に確保されていますか? Q2 クラス内にクラス class BB{ int u,v; AA aa; }; BB *b0 = new BB(); とした場合、 b0がヒープに確保されるとして、 b0->aaはヒープに確保されており、 b0->aa.xやb0->aa.dat[0]等もヒープに確保されているという ことで良いでしょうか? Q3 確認方法 変数等がヒープかスタック領域のどちらに確保されたかは どうやって見分けることができますか? アドレスの値から判断できますか? よろしくお願い致します。

  • static付き宣言の初期化

    static付きの宣言をした場合の変数の初期化について教えてください。(ANSI-C) int func(void) { static int si; static char sca[10]; static char *scp; /* 何らかの処理 */ return 0; } このように関数内でstatic付きで宣言したとき、変数はどのように初期化されますか? siは0、sca[0]からsca[9]までは'\0'、scpはNULLで初期化されますか? また、このようなstatic付きの宣言が関数の外にあった場合は、どのように初期化されますか?

  • VC++ 再帰呼び出しについて

    VC++6.0にてプログラミングを行っているものですが、 関数の再帰呼び出しについて質問です。 再帰呼び出しの際にスタックに積まれる変数というのは、 再帰呼び出しをする関数に渡す引数のことですか? スタックオーバーフローを起こさないために、 staticなポインタにHeap領域上の 変数を割り当てるとよい。 と分かったのですが、 この意味は、例えば static int *a = new int; ということなのですか?

専門家に質問してみよう