• ベストアンサー

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

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

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

  • ベストアンサー
  • rinkun
  • ベストアンサー率44% (706/1571)
回答No.6

ローカル変数の場合はスタック上に動的に割り当てられるのでプログラムサイズに直接の影響はないですね。 配列サイズが100と1000と100000だと割当サイズを表現するのに必要なバイト数の違いで影響が出る可能性はありますけど。 静的変数の場合は、多くの人はプログラムサイズに直接反映されると思っているようですが、配列を初期化しなければ変数は非初期化データ領域に割り当てられて、これはプログラムサイズに直接は反映されないですね。 プログラムのメモリ領域は以下のように分類されます。 1. コード領域 (実行専用) 2. 参照専用データ領域 (読み取り専用) 3. 初期化済変数データ領域 (読み書き可能) 4. 非初期化変数データ領域 (読み書き可能) 5. ヒープ領域 (読み書き可能) 6. スタック領域 (読み書き可能) # 3は初期値を2に置き変数は4に置くという実装もある これらの領域のうち、通常プログラムに含まれるのは1,2,3で、4,5,6はそれぞれのサイズのみ記録されます。 実行時のメモリ上では4,5,6も展開されますが、Linuxのような多重仮想空間対応のOSだと5,6は2GB(だか3GBだか)のアプリケーション・アドレス空間のうち1~4を除いた部分を5,6共用で割り当てる実装でもかまわないので、実行時のメモリ使用量もヒープとスタックの遣い方次第としか言いようがないかも。

f_attck
質問者

お礼

御回答ありがとうございます。 私が望んでいた答えを全て答えて頂き感謝です。

その他の回答 (5)

  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.5

>グローバル変数とした場合はどうなるのでしょうか? C言語のコード生成の実装方法や、実行する環境(プラットホーム、OS)により実行形式ファイルの実装方法が異なり「こうなる」と言う決まりがありません。 グローバル変数サイズを変えた時、あるOS上の実行モジュールでサイズ変化があったからと言って、別のOS上の実行モジュールでサイズ変化があるとは限りません。 また、同じOS上の実行モジュールでも、i386系CPU用C言語のようにメモリモデルと言う概念を組み込んだ実装では、メモリモデルの違いにより変化します。 Linux上で言えば、gccのバージョンの違い、コード生成部のバージョン違い、オプティマイザのバージョン違いにより、グローバル変数のサイズを変えた時の実行モジュールの大きさの変化は千差万別です。 ですので、やはり「実行時の使用メモリ量は実行してみないと判らない」です。

f_attck
質問者

お礼

そうですよね~ やっぱりコンパイラに依存してしまいますよね~ 参考になりました。 ありがとうございます。

  • ymmasayan
  • ベストアンサー率30% (2593/8599)
回答No.4

> 変数のサイズではなく、プログラムがバイナリとなった場合に > どれだけの差になっているかとそのバイナリを実行した場合の > 占有メモリサイズの差を知りたいのですが・・・ 変数(配列)のサイズ差=バイナリプログラムのサイズ差 =そのバイナリを実行した場合の占有メモリサイズの差 で全部同じです。 ただ、エリアが動的に確保される場合には、バイナリプログラムのサイズ差=0になります。

f_attck
質問者

お礼

御回答ありがとうございました。 参考になります。

  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.3

配列がどの空間に宣言されたかによります。 静的メモリ空間(staticな空閑)に配置された場合、生成されたモジュールの静的データ領域のサイズが配列の要素数に影響され、モジュールのサイズが変わります。 動的メモリ空間に配置された場合、メモリは実行時に確保される事になり、モジュールのデータ領域のサイズは変化しません。 但し、確保するサイズにより、プログラム中の命令コードが変化するので、モジュールのプログラム領域のサイズに影響が出て、モジュールのサイズが変わる事があります。 (定数10をレジスタにストアする命令と、定数100000をレジスタにストアする命令とでは、命令コードの長さが違ってきます) なお、実行時のメモリ空間は、変数が配置されたメモリ空間の属性により、多様な使われ方をします。つまり、配列サイズを変えてもまったく変化しなかったり、配列サイズを1バイト変えただけで数万バイトの変化が現われたり、プログラムの実行順序が変わっただけで大きい変化が現われたりします。 結論を言えば「実行時の使用メモリ量は実行してみないと判らない」です。

f_attck
質問者

お礼

レジスタの話、参考になりました。 助かります! 御回答ありがとうございました。

  • K-1
  • ベストアンサー率21% (832/3844)
回答No.2

ローカル変数の場合、アプリ動作時にスタックエリア等から切り出されます。 ですので、生成モジュール自体のサイズは変わらないはずです。 スタティック変数の場合、生成モジュール内にエリアが確保されます。 ですので、生成モジュールのサイズは変化します。

f_attck
質問者

お礼

御回答有難う御座います。 大変解りやすい説明で助かります。 グローバル変数とした場合はどうなるのでしょうか? よろしければ、ご教授戴けないでしょうか よろしくお願いいたします。

noname#16765
noname#16765
回答No.1

printf("サイズは%dバイトです\n",sizeof(hoge)); としたらバイト数が見れます。

f_attck
質問者

補足

変数のサイズではなく、プログラムがバイナリとなった場合にどれだけの差になっているかとそのバイナリを実行した場合の占有メモリサイズの差を知りたいのですが・・・ 質問の[]20]は[20]の間違いです。

関連するQ&A