こんばんは。
表題の通り、セクション領域に関して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&Aを見た人が検索しているワード

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

QLISPのマクロと他の言語のマクロの違い

LISPのマクロは強力と言われていますが、他の言語の言うマクロとはどう違うのでしょうか?

Aベストアンサー

ここでいう「マクロ」は一言で言うと「プログラムを生成する機能」ですね。
例えばCのマクロを例に上げますと、
#define MAX(a, b) (a) > (b) ? (a) : (b)
というようなマクロを定義すると、後に
MAX(10, x)
と書いた際に
(10) > (x) ? (10) : (x)
というプログラムがコンパイル時に生成されます。

Cなどのマクロは、マクロ専用の文法があり、
マクロで書けるものにはある程度の制限が付きます。例えば、
「マクロの引数が定数の際に奇数か偶数かで『生成するプログラム』を変える」
などといった複雑なことはできません。

一方、Lispのマクロは、Lispそのもので書くことが可能で、
任意のプログラムをマクロとして書くことができます。
マクロの中で条件分岐やループなど、なんでも出来てしまいます。
これにより、コンパイル時にマクロの引数の型や値に応じて
生成するプログラムを変えることで最適化を行ったり、
新たな言語機能(と対応する文法)を追加するようなことが可能です。

例えば、昔のLispにはオブジェクト指向の機能がありませんでしたが、
マクロを使うことで、後からオブジェクト指向の機能を付け加えることができました。
また、Common Lispのオブジェクト指向の機能が独特で嫌いな人は、
マクロを使うことでJava風のオブジェクト指向の機能を追加するようなことも可能です。
極端な話、Lispの上で別の言語が作れてしまうわけです。

コンパイル時に任意のプログラムを実行できるという点では、
C++のテンプレートとも似ているといえますが、
C++のテンプレートはテンプレート専用の文法を用いる必要ある点がLispと異なります。
C++をそれなりに書ける人でも、テンプレートで任意のプログラムを書こうとすると、
かなりの苦労を強いられます。テンプレートの文法がC++の文法と異なるのが苦労する原因の一つです。
一方、Lispのマクロは、Lisp自身で書けるため、
Lispが書ける人なら誰にだって書けてしまうわけです。

以上がLispのマクロが強力と言われる要因(の一部)です。
実際に使われてみると色々と実感できると思いますよ。

ここでいう「マクロ」は一言で言うと「プログラムを生成する機能」ですね。
例えばCのマクロを例に上げますと、
#define MAX(a, b) (a) > (b) ? (a) : (b)
というようなマクロを定義すると、後に
MAX(10, x)
と書いた際に
(10) > (x) ? (10) : (x)
というプログラムがコンパイル時に生成されます。

Cなどのマクロは、マクロ専用の文法があり、
マクロで書けるものにはある程度の制限が付きます。例えば、
「マクロの引数が定数の際に奇数か偶数かで『生成するプログラム』を変える」
などといった複雑なことはで...続きを読む

Qメモリ領域を

char s[65536];
char s0[65536];

と大きなWindowsプログラムの中で宣言するとプログラムのコンパイルはとおり実行もほとんど問題ないのですが
メインウィンドウのサイズ変更をしようとするとエラーになります
そこで

char s[999];
char s0[999];

と宣言を変更すると全く問題無く動きます

メモリ領域を大きく使えるような設定とかあるのでしょうか?

OSはWin98でコンパイラはBorland C++5.51でAPIかつ非統合環境で組んでいます

Aベストアンサー

> メモリ領域を大きく使えるような設定とかあるのでしょうか?
スタックサイズを大きくする、ということすれば大きなローカル変数を確保することができます。
Borland C++5.51は詳しくないですが、
コンパイラかリンカのオプションで指定できるのではないかと思います。

Qlispとその他関数型言語について

「lispを学べば悟りが開ける」という言葉をよく聞きます。

l他のプログラミング言語哲学とは一線を画すほどの教示をもった言語という印象を持ちます。

僕もlispを少し学んだだけですが「悟り」は開けませんでした。

しかし他の関数型言語(haskellとか)ではそういう話は聞きません。

なぜでしょうか。

やっぱ括弧ですか。

Aベストアンサー

他の言語が、まだまだ歴史が浅く、使っている人、特にカリスマと呼べるような人が少ないからではないでしょうか。
それに「haskellを学べば..」などといまさら言っても、二番煎じになってしまいますし。

Qメモリ領域の確保の仕方

お世話になります。
メモリ領域の確保の仕方とポインタの動向についての質問です。
呼び出し側の関数testで領域Aを確保する。
関数test内で確保した領域に作業領域Bを加え作業をする。
関数testを抜けるときにreallocで呼び出し側から得た
サイズに領域Aを戻す。
このときの動作についてなんですが
//呼び出し側
void Main(){
  DATA *data_p;//データ構造体
  long datacount = 5;//データ数(5はテスト用の可変値
  data_p = (DATA*)malloc(sizeof(DATA)*datacount);
  test(data_p,datacount);
  free((void*)(data_p);
}
//関数test
test(DATA data[],long datacount){
  DATA *sagyodata_p;
  long a = datacount+5;
  sagyodata_p = data;
  //作業用に領域を広げる
  sagyodata_p = (DATA*)malloc(sizeof(DATA)*a);
  //領域サイズを戻す
  realloc(((void*)sagyodata_p),sizeof(DATA)*datacount);
}
としたときに
関数testでdata_pを参照したポインタsagyodata_pの中身は問題ないでしょうか?
現在の実行環境 .NET2003 C++では問題なく動いているようですが。
sagyodata_p = data;
sagyodata_p = (DATA*)malloc(sizeof(DATA)*a);
とするより、
realloc(((void*)data),sizeof(DATA)*a);
としたほうがよいのでしょうか?
この2つの違いがどのくらいあるのかお教えいただけたら
助かります。
よろしくお願いします。

お世話になります。
メモリ領域の確保の仕方とポインタの動向についての質問です。
呼び出し側の関数testで領域Aを確保する。
関数test内で確保した領域に作業領域Bを加え作業をする。
関数testを抜けるときにreallocで呼び出し側から得た
サイズに領域Aを戻す。
このときの動作についてなんですが
//呼び出し側
void Main(){
  DATA *data_p;//データ構造体
  long datacount = 5;//データ数(5はテスト用の可変値
  data_p = (DATA*)malloc(sizeof(DATA)*datacount);
  test(data_p,datacoun...続きを読む

Aベストアンサー

メモリリークしています。
>  //作業用に領域を広げる
>  sagyodata_p = (DATA*)malloc(sizeof(DATA)*a);
によって,以降(せっかく渡された)dataの指すオブジェクトではなく
新たに確保された領域に対して操作することになります。
しかも,freeしていません。
渡されたdataのサイズを変更したいのであればdataをreallocしましょう。
現状,Mainで確保したdata_pはtest使われずにそのままfreeされています。

・キャストについて
void*へのキャストは冗長なだけです。
# その逆はC++のことを考えるとしてもいいかも。

#include<stdlib.h>
typedef int DATA; // 構造体の代わり
void test(DATA ** data, long datacount){
long a = datacount + 5;
void * tmp;

//作業用に領域を広げる
if ((tmp = realloc(*data, sizeof(DATA)*a)) == NULL){
return; // 適当に復旧
}
*data = tmp;

// ここでdataをごにょごにょ
// :

//領域サイズを戻す
if((tmp = realloc(*data, sizeof(DATA)*datacount)) == NULL){
return; // 適当に復旧
}
*data = tmp;
}
int main(void){
DATA *data_p;
long datacount = 5;
data_p = malloc(sizeof(DATA)*datacount);
test(&data_p, datacount);
free(data_p);
}

メモリリークしています。
>  //作業用に領域を広げる
>  sagyodata_p = (DATA*)malloc(sizeof(DATA)*a);
によって,以降(せっかく渡された)dataの指すオブジェクトではなく
新たに確保された領域に対して操作することになります。
しかも,freeしていません。
渡されたdataのサイズを変更したいのであればdataをreallocしましょう。
現状,Mainで確保したdata_pはtest使われずにそのままfreeされています。

・キャストについて
void*へのキャストは冗長なだけです。
# その逆はC++のことを考える...続きを読む

QLISPで C言語のフォーマット書式の"%02d"

LISPで C言語のフォーマット書式の"%02d"にあたる記述の仕方がわかりません。どのようにすればよいのでしょうか?

Aベストアンサー

Common Lisp で良いのですよね?

(dolist (num '(5 10 200))
(princ (format nil "~2,'0D~%" num)))

実行結果:
05
10
200


format関数
http://www.yuasa.kuis.kyoto-u.ac.jp/~hiraisi/format-func.html

QC言語のメモリ領域確保

ポインタ変数ををmain関数で宣言し、関数test()にて必要分だけ領域確保してそのアドレスをmain関数のポインタ変数に渡して利用することは可能でしょうか。
(サイズのわからないテキストデータを、十分に大きな配列に入れるのではなく、関数でメモリを動的確保して無駄の無い配列に入れたい等)

C言語ではやはり無理で、構造体のリストにするのが一番でしょうか。
初歩的なことで申し訳ありませんがどなたかお願いいたします。

Aベストアンサー

関数getmem中で指定バイト数のメモリを動的に確保し、
main関数にポインタを返します。
main関数中で、確保したメモリに文字列を格納します。
最後にmain関数中でfreeします。
(蛇足ですが、個人的にはこの方法はあまり良くないと思います。
というのも、メモリを確保する場所と、解放する場所が別の関数に
別れてしまうので、freeを忘れがちになると思います。
実際、下記のコードを最初書いた際には忘れてしまい、
見返した時に思い出しました。)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void * getmem(size_t size);

int main(void)
{
char * buf = getmem(10);
strncpy(buf, "message", 10);
printf("%s\n", buf);
free(buf);
return 0;
}

void * getmem(size_t size)
{
void * ptr = malloc(size);
if(ptr == NULL)
{
fprintf(stderr, "cannot allocate memory.\n");
exit(EXIT_FAILURE);
}
printf("allocated memory %d bytes.\n", size);
return ptr;
}

関数getmem中で指定バイト数のメモリを動的に確保し、
main関数にポインタを返します。
main関数中で、確保したメモリに文字列を格納します。
最後にmain関数中でfreeします。
(蛇足ですが、個人的にはこの方法はあまり良くないと思います。
というのも、メモリを確保する場所と、解放する場所が別の関数に
別れてしまうので、freeを忘れがちになると思います。
実際、下記のコードを最初書いた際には忘れてしまい、
見返した時に思い出しました。)

#include <stdio.h>
#include <stdlib.h>
#include...続きを読む

Qlispの入門書

lispの入門書を探しています。

lispの書き方をただ説明するだけでなく、他の言語と違ってどういう利点が
あるのかを説明したものがいいです。

なにかおすすめの本があったら教えてください。

Aベストアンサー

・The Little Schemer
Lispの最高の入門書です。一問一答を追っていくことで、リスト操作やLispプログラムを作っていく感覚について皮膚で理解できるようになります。
英語ですが、難しい文章はないのでそれほど問題ないはず。
環境の整えかたなどの記述はいっさいありません。 "Lisp" を実践して学ぶ本です。

・プログラミングGauche
Lispの方言の一つにSchemeという言語があります。その一つの処理系であるGaucheの本です。さいきん出たばっかり。
Gauche のさまざまな組み込み関数を利用することで関数型プログラミングを実践していきます。
日本語で勉強したいならこちらです。

・リスト遊び
日本語だとこの辺も入門書です。あまり詳しく知りませんが、Emacs Lispの本です。
筆者はEmacs上でemailを読めるMewというソフトウェアの開発者でもあるそうです。

Lispの良さについてはネット上の文章を読む方がよろしいかと。適当に、LispとかPaul GrahamとかShiroとかのキーワードを探してみてください。
「ハッカーと画家」を読むのも良いですね。


Lispコミュニティにコミットするのがいちばんですが。

・The Little Schemer
Lispの最高の入門書です。一問一答を追っていくことで、リスト操作やLispプログラムを作っていく感覚について皮膚で理解できるようになります。
英語ですが、難しい文章はないのでそれほど問題ないはず。
環境の整えかたなどの記述はいっさいありません。 "Lisp" を実践して学ぶ本です。

・プログラミングGauche
Lispの方言の一つにSchemeという言語があります。その一つの処理系であるGaucheの本です。さいきん出たばっかり。
Gauche のさまざまな組み込み関数を利用することで関数...続きを読む

Q消滅したローカル変数のメモリ領域への上書きについて

Cプログラミング初心者のものです。
課題でわからないところがあるので質問いたします。

以下ソース

typedef struct comp{
int val1;
int val2;
}*comp_t,comp_val;

comp_t first();
void second();

int main(int argc, char **argv){
comp_t ret;
ret=first(val);
second();
printf("Val1=%d,Val2=%d\n",ret->val1,ret->val2);
}

comp_t first(){
comp_val comp;
comp.val1=10;
comp.val2=20;
return &comp;
}

void second(){
int a=-100;
int b =-200;
}

実行すると
Val1=-200,Val2=-100
と出ます。ローカル変数が消滅し、second()で新たなintを二つ定義しているので、キレイに上書きされて結果が出たことはわかるのですが、
それなら普通、-100,-200の順に出るのではないのでしょうか。
なぜ裏返ってしまったのでしょう?
また、それはソースを見ただけでわかるものなのでしょうか。
返信お願いします。

Cプログラミング初心者のものです。
課題でわからないところがあるので質問いたします。

以下ソース

typedef struct comp{
int val1;
int val2;
}*comp_t,comp_val;

comp_t first();
void second();

int main(int argc, char **argv){
comp_t ret;
ret=first(val);
second();
printf("Val1=%d,Val2=%d\n",ret->val1,ret->val2);
}

comp_t first(){
comp_val comp;
comp.val1=10;
comp.val2=20;
return &comp;
}

void second(){
in...続きを読む

Aベストアンサー

思いっきり処理系依存な話ですが、一般的なC言語処理系というかコンパイラの出力では、そのような答えになる場合が多いと思います。
なぜそうなるのかはC言語のソースではなく、アセンブラ出力を見れば確実にわかりますが、

・C言語のたいていの処理系(コンパイラ)では、自動変数は「スタック」を使って実現しています。
・大抵の実行環境(CPU)では、スタックはアドレスの「後ろ」から順に使っていくようになっています。

以下、int が4バイトとして書きます。
・first関数
スタックの末尾に8バイトを自動変数 comp 用に確保します。
その8バイト内では、構造体のメンバが val1 、val2 の順に並んでますから、
val1 のアドレス: スタック末尾-8バイト(変数の確保位置)+0バイト(構造体内での位置)
val2 のアドレス: スタック末尾-8バイト(変数の確保位置)+4バイト(構造体内での位置)= スタック末尾-4バイト
になります。

・second 関数
変数a、変数bの順にスタック末尾から4バイトずつ確保されます。
a のアドレス: スタック末尾-4バイト
b のアドレス: aのアドレス-4バイト = スタック末尾-8バイト

結果、comp.val1 とb、comp.val2 とa がスタック上の同じアドレスに割り当てられることになります。

main 関数内で、 printf("&argc=%p, &argv=%p, &ret=%p\n", &argc, &argv, &ret);
first 関数内で、printf("&comp=%p, &comp.val1=%p, &comp.val2=%p\n", &comp, &(comp.val1), &(comp.val2));
second 関数内で、 printf("&a=%p, &b=%p\n", &a, &b);

というコードを追加してみれば、どんな感じでスタックが消費されてアドレスが変わっていくのかが少しは見えると思います。

思いっきり処理系依存な話ですが、一般的なC言語処理系というかコンパイラの出力では、そのような答えになる場合が多いと思います。
なぜそうなるのかはC言語のソースではなく、アセンブラ出力を見れば確実にわかりますが、

・C言語のたいていの処理系(コンパイラ)では、自動変数は「スタック」を使って実現しています。
・大抵の実行環境(CPU)では、スタックはアドレスの「後ろ」から順に使っていくようになっています。

以下、int が4バイトとして書きます。
・first関数
スタックの末尾に8バイトを自...続きを読む

Q初めて関数型言語を学ぶとしたら、どの言語がお奨めですか?

初めて関数型言語を学ぶとしたら、どの言語がお奨めですか?
JavaScriptをやっていて、関数型言語に興味を持ちました。

いままで、勉強した言語はC < Java < Python < JavaScriptです。(右側の方が比重・興味が大きい)
現在、Web系志望の学生なので、その辺を踏まえてアドバイスいただけると助かります。

今のところ興味を持ってるのは、Common Lisp/Haskellあたりです。

よろしくお願いします。

Aベストアンサー

C言語が「関数型」?なのか、と言われると多分違うと思うんですけどね。普通は命令型/手続き型に分類されるんじゃないか、と思います。

ちなみに、JavaScriptはSchemeに影響を受けてる言語です。それで言うと、SchemeかCommon Lispがいいんじゃないのかな、とは思いますがね。ただ、あんまり関数型、って感じで書かれている本は少ないと思います。

Web系志望と言う事なんで、Common Lispですと、

ANSI Common Lisp: http://www.pej-hed.jp/washo/288.html
にHTML生成のトピックあり。

実践Comon Lisp: http://ssl.ohmsha.co.jp/cgi-bin/menu.cgi?ISBN=978-4-274-06721-1
にAllegro Serveと言うライブラリを利用したWebプログラミングの例があり。HTML生成の例もあり。
原著のサイトでは、
http://www.gigamonkeys.com/book/practical-web-programming-with-allegroserve.html
http://www.gigamonkeys.com/book/practical-an-html-generation-library-the-interpreter.html
http://www.gigamonkeys.com/book/practical-an-html-generation-library-the-compiler.html
辺り。

プログラミング言語Lisp: http://ascii.asciimw.jp/books/books/detail/4-7561-3926-4.shtml
CL-HTTPと言うライブラリを用いたWebサーバーの説明が載っています。
ただし、本自体はMacintosh用の商用実装、Mac Common Lisp

Mac Common Lisp:
http://www.digitool.com/

を用いたものなんで、注意する必要があります。Macを持ってないならあまりお薦めしません。また、若干古い本ですね。

Haskellの方は良く分かりませんが、Common LispならそれなりにWeb関係の簡単なアプリの書き方も紹介されている、と言う事です。

参考までに。

C言語が「関数型」?なのか、と言われると多分違うと思うんですけどね。普通は命令型/手続き型に分類されるんじゃないか、と思います。

ちなみに、JavaScriptはSchemeに影響を受けてる言語です。それで言うと、SchemeかCommon Lispがいいんじゃないのかな、とは思いますがね。ただ、あんまり関数型、って感じで書かれている本は少ないと思います。

Web系志望と言う事なんで、Common Lispですと、

ANSI Common Lisp: http://www.pej-hed.jp/washo/288.html
にHTML生成のトピックあり。

実践Comon Lisp: http://s...続きを読む

QDLLで同じメモリ領域を参照するには?

現在、DLLを作成しています。

ある実行ファイル(exe)から呼び出された時に、
DLLでメモリを確保し、データを保持します。

また、別の実行ファイル(exe)から呼び出された時に、
最初に保持したデータの内容を返したいのですが、
どこにどういう定義でメモリを確保すれば
同じ領域が参照できますか?

現時点の状態では、別タスクであるため、最初に確保した
メモリのアドレスすら持って来れません。

申し訳ありませんが、教えてください。
よろしくお願いいたします。

Aベストアンサー

基本的に、そういうことはプロセス間通信なので、メッセージやメモリマップとファイルを使うのがスジです。
仮想メモリって分かってますか?

が、Microsoft の場合には、お手軽なやり方として、shared セクションにデータを置く手があります。

http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vccore/html/_core_how_do_i_share_data_in_my_dll_with_an_application_or_with_other_dlls.3f.asp

参考URL:http://techtips.belution.com/ja/vc/0023/,http://www.h4.dion.ne.jp/~fht/htmkdll/


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング