ついに夏本番!さぁ、家族でキャンプに行くぞ! >>

こんばんは。
表題の通り、セクション領域に関して3点ほどご質問が御座います。

(1)グローバル変数は、
 ・0でない初期化を行う→.dataセクション
 ・0で初期化、または、初期化なし→.bssセクション
 上記のようにメモリに配置されると思いますが、
 上記をstatic宣言した場合でも結果は同じでしょうか?
 (static宣言したグローバル変数)

(2)スタック、ヒープそれぞれが属するセクションは、それぞれ専用の
 スタックセクション、ヒープセクションという名のセクションがあるという認識であっていますでしょうか?
 (.dataでもなく、.bssでもなく、.textでもなく、.rodataでもなく。。。)

(3)プログラム中に宣言した変数名や、そのアドレスを使用して、属しているセクションを確認することが出来る方法はありますでしょうか?

どうかご教授をお願い致します。

このQ&Aに関連する最新のQ&A

A 回答 (3件)

> (1)グローバル変数は、


> 上記をstatic宣言した場合でも結果は同じでしょうか?
> (static宣言したグローバル変数)

静的グローバル変数はシンボルの公開が抑止されるのみでその他に違いはない場合が多いかと。


> (2)スタック、ヒープそれぞれが属するセクションは、それぞれ専用の
> スタックセクション、ヒープセクションという名のセクションがあるという認識であっていますでしょうか?

ありません。


> (3)プログラム中に宣言した変数名や、そのアドレスを使用して、属しているセクションを確認することが出来る方法はありますでしょうか?

通常、各アドレスはまとまっている(例えば1000-2999はtextで3000-3999はbss,4000-5999はdataの様に)のでアドレスを調べれば解ります。
実行ファイルの形式上情報がありますので実行ファイルを解析すれば各セクションの位置や大きさはわかります。(詳しく知りたい場合にはunix系のsizeコマンドのソースを参照するのも良いかと)
elf形式やaout形式にマニュアルページやヘッダなども知る上で良い資料となりそうに思います。
※javaやC++には固有のセクションが追加されている場合があったり。


> (3)プログラム中に宣言した変数名や、そのアドレスを使用して、属しているセクションを確認することが出来る方法はありますでしょうか?

通常、アドレスを調べれば解ります。

予約された領域を除き残った領域を下位アドレスからヒープとして、上位アドレスからスタックとして動的割り当てしたりするのではないかな。
    • good
    • 0
この回答へのお礼

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

お礼日時:2011/04/20 19:43

「一般的」ってどういうこと?



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

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

    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
>何か特定の処理系を想定しているように見えるので,
 →いえ、こちらはあくまで一般的な事例をご教授いただけたらと思っています。

>その処理系でやってみればわかるんじゃないの?
 →質問(3)の通り確認の仕方が不明です。

お礼日時:2011/04/19 20:19

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q組み込みソフト。ROM領域にデータ

C でデータに const 属性をつけて、初期値を設定して定義すると、初期値は ROMにテーブルが作られますがデータ自体は RAM領域に配置されます。
RAMの節約のため、ROM領域にデータを配置する方法はないのでしょうか。

Aベストアンサー

#pragma section data = ".rodata"
//ROM配置したいデータ

#pragma section data = default

等のコンパイラやアセンブラのコマンドを使ってデータが配置される領域をROM領域に設定してください。
必要に応じてリンカディレクティブファイルまたはリンクディレクティブなどと呼ばれるファイルを編集してROM領域を示すセクションを追加してください。

注)他の回答にあるようにあなたの使用している環境に合わせてください。

Qバイナリデータとテキストデータの違いについて

宜しくお願いします。

バイナリデータを用語辞典で調べると
「テキスト形式(文字データ)以外のデータ形式全般のこと。
実行可能形式のコンピュータプログラムや、画像や音声、
動画などのデータなどがバイナリデータにあたる。」
(http://e-words.jp/w/E38390E382A4E3838AE383AA.html)
とあります。

これでは、バイナリデータとテキストデータの違いが分かりません。

テキストデータはコードの集まりで、
さらに細かくすると0と1の集まり(?)だから・・・
と考えるとバイナリデータとテキストデータの
違いが分かりません。

Q1.私は何が分かっていないのでしょうか?
Q2.バイナリデータとテキストデータの違いを教えてください。

宜しくお願い致します。

Aベストアンサー

バイナリデータは01の集まりです。
テキストデータは文字としての意味が与えられて居ます。ただテキストデータの01としての表現方法はプラットフォーム(OSやアプリケーション)によって異なります。例えば英文字コードでもメインフレームで使われるEBCDICもあり、unixやPCで使われるASCIIもあります。また日本語など英語以外の文字をあらわすのには、さらに多くの種類があります。また改行を表す文字もいろいろです。
例えば telnet で他のコンピュータにログオンして通信する時の文字コードはASCIIで、改行はCRLFと決まっているので、そうでないコンピュータはtelnetプログラムが自分のコンピュータのコード体系と相互変換します。

ftpでテキストデータを転送する時も同じくASCIIとCRLFと決まっています。ただ日本語文字の時にどのコードを使うかは規格では決まっていないので、ftpクライアントで、相手コンピュータの日本語コード種類を指定して、自分と合わなければ転送時に相互変換します。

Cプログラムでもテキストの改行は'\n'と決まっているので、そうでないWindowsの場合はCプログラムとの間でCRLFと'\n'の相互変換が、ライブラリ中で自動的に行われます。

そういった変換を全く行わないのがバイナリデータです。画像ファイルなどはjpegと形式が決まればどのコンピュータでも同じフォーマットなので変換の必要はありません。逆にテキストとみなして変換するとデータが壊れてしまいます。

バイナリデータは01の集まりです。
テキストデータは文字としての意味が与えられて居ます。ただテキストデータの01としての表現方法はプラットフォーム(OSやアプリケーション)によって異なります。例えば英文字コードでもメインフレームで使われるEBCDICもあり、unixやPCで使われるASCIIもあります。また日本語など英語以外の文字をあらわすのには、さらに多くの種類があります。また改行を表す文字もいろいろです。
例えば telnet で他のコンピュータにログオンして通信する時の文字コードはASCIIで、改行はCRL...続きを読む

Qint型からchar型への変換

タイトル通り、int型からchar型への変換の仕方がわかりません!><
どうしたらいいのでしょうか?

Aベストアンサー

#include <stdio.h>


char buf[5];
int no;

no = 10;
sprintf(buf, "%d", no);

QC言語のポインタに直接アドレスを割り振りしたい

C言語のポインタに直接アドレスを割り振りしたいのですが、どうしたら良いのでしょうか?

Aベストアンサー

直接アドレスを割り振りたい、というのは
int* pnValue;
pnValue = (int*)0x12345678
ということでしょうか?このようにすればポインタにアドレスを代入することはできるかと思います。

Qマイコンのメモリマップについて

マイコンに限った話ではないかとは思いますが、現在マイコンプログラムの勉強をしておりますが、マイコンのデータシートのメモリマップを見ると先頭番地からフラッシュメモリのマッピングがあり、その次に各種レジスタやRAMのマッピングがなされています。

(1)このメモリマップというものは論理アドレスと物理アドレスの対応表のようなものだと解釈しておりますが、この対応表自体はRAMの一部に格納されているのでしょうか?

(2)例えばフラッシュメモリの物理アドレスが00~FFまであり、RAMの物理アドレスも00~FFだった場合で且つ
フラッシュメモリの後ろにRAMのマップを作る場合、メモリマップの中の論理アドレスは00~2FFまでで物理アドレスはフラッシュメモリの部分は00~FF,RAMのブツリアドレスも00~FFになるという理解で良いですか?

ひょっとするとかなり見当違いをしている質問かもしれません。
よろしくお願いします。

Aベストアンサー

うーん、なんかピンとこないですね。
何か勘違いしてるかも。

1)一般的にメモリマップとは、どこからどこまでのアドレスにどんなハードウェアが接続されているかとか何に使われているか。の図です。
000000-00ffff:フラッシュメモリ
010000-010fff:レジスタ
011000-0fffff:メインメモリ
という感じなはずです。

メインメモリで、ここからここはこれ、という図も「メモリマップ」です。
区別するなら「メインメモリのメモリマップ」です。

2)1)で書いたメモリマップ内00000-fffffで、レジスタの先頭は10000から始まります。
そのレジスタだけに注目した場合、相対的な位置は000-fffの範囲になります。
この相対的な位置のことを「論理アドレス」と言っているのでしょうか。

「論理アドレス」「物理アドレス」とは仮想記憶を使う場合に使用する用語です。
バンク切替などを行わない場合、この言葉は使いません。
固定のメモリマップの場合、単に「アドレス」というだけです。
あえていうなら「相対アドレス」ですが、かえってややこしくなるので普通は使いません。

うーん、なんかピンとこないですね。
何か勘違いしてるかも。

1)一般的にメモリマップとは、どこからどこまでのアドレスにどんなハードウェアが接続されているかとか何に使われているか。の図です。
000000-00ffff:フラッシュメモリ
010000-010fff:レジスタ
011000-0fffff:メインメモリ
という感じなはずです。

メインメモリで、ここからここはこれ、という図も「メモリマップ」です。
区別するなら「メインメモリのメモリマップ」です。

2)1)で書いたメモリマップ内00000-fffffで、レジス...続きを読む

Qbssって何でしょうか?

UNIXで、2つのファイルの大きさを比べようとしてkterm上でsizeを実行した所、
「 text data bss dec hex filename」
という項目(?)が出て来ました。他の意味は何となくわかるのですが、「bss」の意味だけが全くわかりません。英和辞典を引いてみても、bssで始まる単語なんてありませんし...。どなたか意味を教えてください。
よろしくお願いします。

Aベストアンサー

検索したら見つかりました。
block started by symbol

参考URL:http://wiki.livedoor.jp/yushinhozumi/d/BSS

Q【#define】 defineで定義した値を配列のサイズに使う事は可能?

タイトルの通り、defineで定義した値を配列のサイズ指定に使いたいと考えています。
この場合、次のような使い方をしても問題ないのでしょうか?

/* サンプルここから */
#define SIZE_A 10
#define SIZE_B 20
#define SIZE_ALL (SIZE_A * SIZE_B)

cahr ARR[SIZE_ALL];
/* サンプルここまで */

コンパイル時にワーニング等はありませんが、int型という型を宣言していないSIZE_ALLを要素数として使用するのが不安に感じるのですが問題ないのでしょうか?

int SIZE_int = SIZE_ALL;
とdefineした値を明示的にint型変数に代入した上で、
cahr ARR[SIZE_int];
とすべきなのでしょうか?

初歩的な質問ですが、ご教示お願いします。

Aベストアンサー

★特に問題ありません。
・普通に define された定数を掛け算などして新しい記号定数を定義します。
 そしてその記号定数を配列などの添え字に使います。
 そもそも define された定数は通常は int 型と同じになります。
 #define SIZE_A 10…int型
 #define SIZE_A 10L…long型
 #define SIZE_A 10LL…long long型
 となります。
 『L』や『LL』のサフィックスを付けないとすべて int 型に解釈されます。
 つまり、プリプロセッサ命令は単純な文字列の置換ですのでサフィックスを
 付けないと int 型になるわけですよ。
・もし char 型にしたいならキャストを指定します。
 例えば
 #define SIZE_A ((char)(10))
 とします。
・もう既に回答がありますが
>int SIZE_int = SIZE_ALL;
>とdefineした値を明示的にint型変数に代入した上で、
>cahr ARR[SIZE_int];
>とすべきなのでしょうか?
 ↑
 この方法は新しい記述方法です。
 1999年の最新のC言語の規格です。
 この C99 にすべてのコンパイラが対応しているわけではないため使わない方が
 良いかもしれません。この記述が利用できれば便利なこともありますが…。
・最後にカッコをつけた方が良いですよ。
 #define SIZE_A (10)
 #define SIZE_B (20)
 #define SIZE_ALL (SIZE_A * SIZE_B)
 という風に SIZE_A、SIZE_B に括弧を付けます。
 これは今後 SIZE_A を『10 + 20』と定義した際に括弧がないと計算式が
 正しくなくなるので付けるように習慣を付けておいた方が良いということです。
 つまり今後
 #define SIZE_A 10 + 20
 #define SIZE_B 20 * 3
 #define SIZE_ALL (SIZE_A * SIZE_B)
 と定義したとします。
 すると SIZE_ALL は (10 + 20 * 20 * 3) と置換されますが計算式が掛け算を先に
 する数学上のルールより意図しない結果になります。正しくは SIZE_ALL=1800 に
 なるべくところが SIZE_ALL=1210 となってしまいます。
・これを防ぐには2つ。
 #define SIZE_A (10 + 20)
 #define SIZE_B (20 * 3)
 #define SIZE_ALL (SIZE_A * SIZE_B)
 もしくは
 #define SIZE_A 10 + 20
 #define SIZE_B 20 * 3
 #define SIZE_ALL ((SIZE_A) * (SIZE_B))
 と定義します。
 どちらにカッコを付けても同じですが私はすべてにカッコを付ける派です。
・参考にして下さい。

★特に問題ありません。
・普通に define された定数を掛け算などして新しい記号定数を定義します。
 そしてその記号定数を配列などの添え字に使います。
 そもそも define された定数は通常は int 型と同じになります。
 #define SIZE_A 10…int型
 #define SIZE_A 10L…long型
 #define SIZE_A 10LL…long long型
 となります。
 『L』や『LL』のサフィックスを付けないとすべて int 型に解釈されます。
 つまり、プリプロセッサ命令は単純な文字列の置換ですのでサフィックスを
 付けないと ...続きを読む

Q【gcc・cygwin】multiple definitionエラーの解決法

こんにちは。
C言語のプログラミングをしているのですが、
multiple definition of '関数名'と出てしまいます。

・コンパイルするファイル
program1.c(main文)
program2.c(関数)
program3.c(関数)
すべてのソースファイルが、
header.hをincludeしています。
header.hではすべての関数のプロトタイプ宣言がされています。
program2.cに書いてある関数、test()はすべてのソースファイルで使用しています。

・cygwin上で実行したコマンド
gcc -Wall program1.c program2.c program3.c -o test

・エラーの文章
(パス省略)/ccst1v2u.o:program2.c:(.text+0x0): mult
iple definition of `_test'
(パス省略)/ccyUr2Ku.o:program1.c:(.text+0x0): first defi
ned here

このような事態に陥った場合の解決方法はどのようにすればよいでしょうか?

先輩から引き継いだ、もともと一つのソースファイルに書かれていた多数の関数を、利便性のために分割したところこのようなエラーが発生しました。
先輩から引き継いだもののため、本当の関数名など細かいことをこちらに書き込めないのですが、
出来る範囲で補足いたします。
どうかよろしくお願いいたします。

こんにちは。
C言語のプログラミングをしているのですが、
multiple definition of '関数名'と出てしまいます。

・コンパイルするファイル
program1.c(main文)
program2.c(関数)
program3.c(関数)
すべてのソースファイルが、
header.hをincludeしています。
header.hではすべての関数のプロトタイプ宣言がされています。
program2.cに書いてある関数、test()はすべてのソースファイルで使用しています。

・cygwin上で実行したコマンド
gcc -Wall program1.c program2.c program3.c -o test

...続きを読む

Aベストアンサー

実際にサンプルを作って確認してみましたか?
以下、インデントに全角スペースを使っています。
ソースを公開できないということなので、アドバイスできるのはここまでです。

=======
header.h
=======
#ifndef _HEADER_H_
#define _HEADER_H_
#include <stdio.h>
#include <stdlib.h>
void test1(void);
void test2(void);
void test3(void);
#endif
=====
main.c
=====
#include "header.h"
int main(void)
{
  test1();
  test2();
  test3();
  return 0;
}
=====
test1.c
=====
#include "header.h"
void test1(void)
{
  printf("test1() called.\n");
}
=====
test2.c
=====
#include "header.h"
void test2(void)
{
  test1();
  printf("test2() called.\n");
}
=====
test3.c
=====
#include "header.h"
void test3(void)
{
  test1();
  test2();
  printf("test3() called.\n");
}

実際にサンプルを作って確認してみましたか?
以下、インデントに全角スペースを使っています。
ソースを公開できないということなので、アドバイスできるのはここまでです。

=======
header.h
=======
#ifndef _HEADER_H_
#define _HEADER_H_
#include <stdio.h>
#include <stdlib.h>
void test1(void);
void test2(void);
void test3(void);
#endif
=====
main.c
=====
#include "header.h"
int main(void)
{
  test1();
  test2();
  test3();
  return 0;
}
=====
test...続きを読む

QIG、ACC、+B、ILL

それぞれの電源の意味を教えてください。

IG、ACC、+B、ILL

それぞれどのような役割があるのでしょう?

宜しくお願いします。

Aベストアンサー

IG(イグニッション電源)
   ・・キースイッチがON又はSTARTの位置で12Vの電圧がでる
ACC(アクセサリー電源)
   ・・キースイッチACC又はONの位置で12Vの電圧がでる
+B(バッテリー電源)
   ・・常に12Vの電圧がでる
ILL(イルミネーション電源)
   ・・スモールランプが点灯している時は12Vの電圧がでる

たとえば通常のキースイッチ(OFF-ACC-ON-START)でナビを例にとると
キースイッチがOFFの時、当たり前ですがナビの電源は入りません。
キースイッチをACCまで回すと"ACC"電源が供給されナビの電源が入ります。
キースイッチをONまで回しても"ACC"電源は供給されているのでナビの電源は入ったままです。
キースイッチをSTARTまで回すと"ACC"電源が遮断されるのでナビの電源は切れます。
これはセルが回る際に大電流を必要とするので、他の電気機器の電源をOFFする必要がある為です。
エンジンがかかってキースイッチをONに戻すと、再び"ACC"電源が供給されるのでナビの電源が入ります。
夜間スモールを点灯すると、"ILL"電源が供給されナビの表示が夜用に暗く変化します。
ナビがDVD方式だとすると、キースイッチがOFFの時でも"+B"電源は供給されているのでメディアの出し入れは可能です。

ナビを例にとるとこんな感じです。

IG(イグニッション電源)
   ・・キースイッチがON又はSTARTの位置で12Vの電圧がでる
ACC(アクセサリー電源)
   ・・キースイッチACC又はONの位置で12Vの電圧がでる
+B(バッテリー電源)
   ・・常に12Vの電圧がでる
ILL(イルミネーション電源)
   ・・スモールランプが点灯している時は12Vの電圧がでる

たとえば通常のキースイッチ(OFF-ACC-ON-START)でナビを例にとると
キースイッチがOFFの時、当たり前ですがナビの電源は入りません。
キースイッチをACCまで回すと"ACC"電源が...続きを読む

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

最近H8/3694Fを使ってマイコンの勉強をしております。
HEWを使ってコンパイルするときのセクションの設定に
ついて質問があります。

プログラム・セクションの設定を一通り終え、ビルドすると
「L2321 (E) section "S" overlaps sction "P"」
とエラーメッセージが出てしまいました。

色々調べてみるとSはスタック領域、Pはプログラム領域
でこれに重なりができてしまっているようなのですが、
これ以上どうしてよいのかわからず困っています。

おそらくセクション設定を変更すればよいと思っていますが
プログラム領域にどれくらい、スタック領域にどれくらい
を配置すればいいというのはどうやって求めればよいのでしょう?
HEWのメモリマップを表示させて見る方法があるようですが
見てもいまいちわかりませんでした。

使用環境:OS:WindowsXP、HEW4.04.01.001

以上、追記補足いたします。詳しい方教えていただけないでしょうか

Aベストアンサー

実際のリンク結果のアドレスマップは、「Standard Toolchain」の最適化リンカのオプションを変更すれば出力できるはずです。
「リンクマップファイル」がキーワードでマニュアル等を探してみてください。うまく行けば、[プログラム名].mapの名前で作成されるはずです。

>「L2321 (E) section "S" overlaps sction "P"」
RAMで実行する設定にしたなら、このエラーも納得です。
プログラムが本当に大きすぎるんだと思います。
>0X0000FE80 S
となっていますので、設定を変えていないと0x100サイズのスタックが取られるらしいので、0xFD80-0xFE80はスタックになります。
プログラムの部分のPセクションが、0xFD80を超えてしまっていると思いますよ。


人気Q&Aランキング