• ベストアンサー

C/C++言語のメモリについて

C言語でメモリを2種類?に分けると、スタックとヒープがあります。 ヒープは mallocなどで確保し、freeで解放しますがスタックは解放する必要がありません。 そのスタックは通常、何バイトまで可能なのでしょうか? あと関数外のファイルの先頭に int[1000000];とした場合、このメモリはmallocで確保していませんが、 どこに作られるのでしょうか? 私のパソコンはメモリが2GBでWindows2000ですが、CやC++で最大、何バイトまでメモリが使えますか? また、一番多くメモリを確保できるなら、OSはなんでも構いません。 解釈等も間違っていたらご指摘していただきたいです。

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

  • ベストアンサー
  • Interest
  • ベストアンサー率31% (207/659)
回答No.3

マイコン向けのプログラムを書いてます、Interestと申します。 > C言語でメモリを2種類?に分けると、スタックとヒープがあります。 間違いではありませんが、ちょっと足りません。プログラムで使用するメモリはもう少し細かく見ると、次のようになっています。 (P) 実行される命令(ProgramとかCodeと呼ばれます) (C) 定数など変更されないデータ (D) 初期化されるデータ (B) 初期化されないデータ (H) プログラムから動的に割り当てられるメモリプール(これがヒープです) (S) ローカル変数、関数の引数、呼び出し元関数へのリンクに使用する比較的短命なものに使用するメモリプール(これがスタックです) > そのスタックは通常、何バイトまで可能なのでしょうか? 開発環境によって初期値が決まっているようで、どれだけ割り当てるか変更できるようです。OSには依存しません。Visual C++ 6.0の場合、スタックサイズの初期値は1MBだそうです。 参考 http://okwave.jp/qa2645032.html > あと関数外のファイルの先頭に int[1000000];とした場合、 > このメモリはmallocで確保していませんが、どこに作られる > のでしょうか? 最初に説明した内容に照らすと、一般に外部変数は0で初期化されますから、(D) 初期化されるデータ の領域に確保されることがわかります。 > 私のパソコンはメモリが2GBでWindows2000ですが WindowsなどのOSは物理メモリが足りなければハードディスク上の仮想メモリも使用しますので、単純に何バイトまで使えます、とはお答えできません。 > 一番多くメモリを確保できるなら、OSはなんでも構いません。 どのようなプログラムを組もうとしているのですか?

その他の回答 (5)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.6

> 一番多くメモリを確保できるなら、OSはなんでも構いません。 それならOSなんか使わずに、ハードウェアを直接制御した方が多くのメモリを使えます。 OSもメモリを使いますので、OSがなければその分余分にメモリを使えます。 また、どんなCPUを使うかは知りませんが、特権モードで動作させればすべてのメモリ空間を扱うことができます。

  • furyfox
  • ベストアンサー率56% (58/103)
回答No.5

すみません。スタックデフォルト2Mと書きましたが他の方の指摘の通り1MBが正しいです。 ところでWindowsやLinuxで扱えるアドレスというのは直接物理アドレスを指定できるわけではなく malloc(HeapAlloc)で返るのは仮想メモリ空間のアドレスです。物理メモリがどうなっているかは 特殊なツールを使えばわかりますが、基本的にはCPU以外から参照できません。 malloc(1,000,000,000)、これはできなくても malloc(1,000,000)を1000回取ることは可能だったりします。 それは他の方のいわれるように仮想メモリという使われていないメモリはハードディスクにスワップする 仕組みがあるからです。 ちなみにWindowsXp(32bit)の場合、OS自体は3GBのメモリまで認識できますが 1プロセスが確保できる場合は合計で2GBまでです。 また4GB超のアドレスを使いたい場合は普通、64bitオプションを指定する必要があります。 (void*のサイズが64bitになります。) 最近になって特にメモリを大量に必要とする グラフィック関連のツールやモデラー、ゲームの中には64bit対応したものも出てきています。 有名メーカーのドライバ等も64bit対応してきましたし、今は32bitからの移行期ですね。

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.4

>ヒープは mallocなどで確保し、freeで解放しますがスタックは解放する必要がありません。 >そのスタックは通常、何バイトまで可能なのでしょうか? スタックは関数からリターンするときに解放される為、自分で解放を意識する必要はありません。自動変数はスタック領域に作成されていますので、スタックサイズを超える自動変数は作成してはいません。 で、実際のスタックサイズは他の方が書かれている通りで、VS2005でもデフォルトは1MBみたいです。もちろんオプションで変更可能です。 >あと関数外のファイルの先頭に int[1000000];とした場合、このメモリはmallocで確保していませんが、 >どこに作られるのでしょうか? windowsのメモリ空間から確保されます。mallocで使用するヒープ領域もメモリ空間から確保されています。 ここはWindowsAPIのメモリ関数を勉強すれば、ある程度分かると思います。キーワードは、VirtualAllocとHeapAllocです。理解するためには仮想記憶の知識も必要となりますのでまず勉強してください。 >私のパソコンはメモリが2GBでWindows2000ですが、CやC++で最大、何バイトまでメモリが使えますか? >また、一番多くメモリを確保できるなら、OSはなんでも構いません。 32bitのWindowsでの動作に限った話をすると、1つのプロセス(プログラム)に割り当てられる仮想記憶空間の最大値は4GBで、これは絶対に越えられないメモリ最大値です。 実際には実メモリサイズを超えると実行速度は著しく低下しますから実用レベルで使うには2GBが限界になります。 しかし、2GBも実際にはOSやら他のプログラムがメモリを使用していますし、ファイルのキャッシュとして使われるメモリもある程度必要になりますので、1.2~1.3GB程度が自分のプログラムに使える限界ではないでしょうか? 64bitのOSと64bitで動くCPUを組み合わせれば、4GBを超えることは可能ですが、そこまでメモリが必要なプログラムは設計に何か問題がある気がします。

  • furyfox
  • ベストアンサー率56% (58/103)
回答No.2

Windows + Visual C++の場合、 int a[1000000];にしてもグローバルならヒープにとられるし、関数内ならスタックにとられます。 またメモリを2G搭載しても実際連続領域で取ることができるのは 1Gも無いと思います。(メモリは断片化しています。) malloc(1000000000)とすると恐らく取得に失敗します。 メモリがどれだけ確保できるかはOSの問題であって言語の問題ではありません。 Windowsのmallocも内部でAPIが呼ばれているにすぎません。 Windowsで一番多くメモリを取りたいなら Vista Ultimate 64bit版でしょうか。こちらは最大128Gまで物理メモリを認識する事が出来ます。 (ただし一般に市販されているマザーボードに載るのは大体8GがMAXだと思います。) Solaris64bit版等のサーバー向けの64bit OSなら更に多くのメモリが確保できるかもしれません。 スタックは解放する必要があるのではなく、関数等終了と同時にその領域が使えなくなるというだけです。 普通コンパイル時にスタックのサイズは固定で決めます。 何も指定しないと例えばVisual C++6.0の場合だと2MByteだったと思います。

  • a-saitoh
  • ベストアンサー率30% (524/1722)
回答No.1

スタックサイズの通常の大きさという物はありません。 利用者が、自分の必要に応じて設定する物です。 特に何も設定しない場合の大きさは、OS,コンパイラごとに違います。 スピードに目をつぶるならば、メモリの搭載サイズを超えて割り当てることも可能です(ページファイルが使われる)。 まずは、Cの名前空間と変数の寿命についてちゃんと勉強することをお勧めします。

関連するQ&A

  • C言語におけるローカル変数が使用するメモリについて

    例のようなC言語のプログラムを動かした場合、 確保されるメモリ領域はどうなるのでしょうか。 例 #include <stdio.h> int main(void) { int a = 0; } このとき、変数aはint型なのでスタック領域に4バイトのメモリが確保されると理解しています。 と同時にaという変数名と確保されたスタック領域の番地を紐づけるようなメモリがどこかに確保されるのではないかと思ってるのですが、この理解で正しいでしょうか。 またその場合は変数aの番地はどの領域に確保されるのでしょうか。 ご教示お願いいたします。

  • C言語 動的なメモリの確保 実行できない

    malloc関数を使いメモリを確保しそこへ"ABCD"と記憶させ、ポインタ*Cを使い確保したメモリの内容を表示するプログラムです。 ********************************************* #include <stdio.h> #include <stdlib.h> int main(void) {   int i;   char *C;   C = (char *) malloc (sizeof(char) * 5);   C = "ABCD";   for(i = 0; i < 5; i++){     if(C[i] != NULL){       printf("%s", C[i]);    ←※エラー※     }   }   free(C);   return 0; } ********************************************* 正常にコンパイルできますが実行エラーになります。VCを使いF10のデバッグテストで※のところエラーになります。なぜなのでしょうか?

  • c言語のmalloc関数、またrealloc関数

    c言語のmalloc関数は確保するメモリの領域を、配列としてのみしか処理出来ないのですか。 つまり、malloc関数で確保したメモリの領域を変数、また多次元配列、また構造体としては処理出来ないのでしょうか。 c言語のrealloc関数は以前の確保したメモリの領域から、確保し直したメモリの領域の場所が変わるかもしれないという事ですが、この場合の場所が変わるという意味は、メモリの領域のアドレスが変わるという事でしょうか。 また、以前の確保したメモリの領域に代入していたデータが使用出来なくなるという事でしょうか。

  • 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の実体はスタックではなく、ヒープ領域に確保する気がします、、 どうか、ご教授ください。

  • C++ 最適なメモリ確保

    画像処理をするために実験的にC++でプログラムを書いています。 malloc関数でBMP画像の画素位置を、画像画素分確保するだけのint型配列を作成するにはどうしたらよいでしょうか。 因みに、入力画像の解像度は640x480です。 一番左下の画素を(x,y)=(0,0)として考えています。 ある条件の画素に該当する画素座標を、下のStackX,StackYにx,y成分ごとに格納していくものです。 //////// int *StackX = (int *)malloc(sizeof(int)*100000); int *StackY = (int *)malloc(sizeof(int)*100000); //////// 上のように書くと、途中でクラッシュしてしまいます。 ですが、大目にメモリをとって //////// int *StackX = (int *)malloc(sizeof(int)*10000000); int *StackY = (int *)malloc(sizeof(int)*10000000); //////// で実行すると、最後まで動いてくれます。

  • 動的メモリとexit(C言語)

    fpA=fopen("name1", "r"); fpB=fopen("name2", "r"); fpC=fopen("name3", "r"); if(fpA==NULL || fpB==NULL || fpC==NULL){ exit(1); } fpAとfpBのファイルオープンに成功してfpCで失敗した場合、exit(1)によってfpAとfpBはクローズされますよね? じゃあ、 a=malloc(size); b=malloc(size); c=malloc(size); if(a==NULL || b==NULL || c==NULL){ exit(1); } aとbのメモリ確保に成功してcで失敗した場合、aとbのメモリはどうなっちゃうんでしょう?exitは動的メモリも解放してくれるのですか? とりあえず以下のようにしてますが…。 a=malloc(size); b=malloc(size); c=malloc(size); if(a==NULL || b==NULL || c==NULL){ free(a); free(b); free(c); exit(1); }

  • C言語 mallocによる消費メモリ

    char *b = (char *)malloc(sizeof(char) * 6) というC言語のプログラムで、消費されるメモリは何バイトになるのでしょうか?理由も合わせて教えていただきたいです。 32ビットのPCで行うものとしてよろしくお願いいたします。

  • メモリを解放しないとどうなる?

    趣味でプログラムの勉強をしています。 初歩的な質問になると思いますが、よろしくお願いします。 C言語やC++言語のように、動的に確保したメモリを使用後に意識して解放しないといけない言語で、解放の処理をしないままプログラム(アプリケーション)を終了した場合にはシステム(OS?)的にはどのような状態になるのでしょうか? 例: ・malloc して free しない ・new して delete しない 確保されたメモリ領域がそのまま残り、システムとして使用できるメモリ量が減る(解放にはPCの再起動が必要)のでしょうか? それともアプリケーションの終了時に自動的に解放されるのでしょうか? Windowsの場合を想定してご回答いただだけると嬉しいです。

  • c言語のメモリリークについての質問

    c言語のメモリリークについての質問 c言語初心者のため、メモリリークについて質問させていただければと存じます。 下記のコードで、 char* char_p = "char1"; char_p = "char2"; // ←メモリリーク? 2行目の部分は、 "char1"のメモリ領域が確保されたままで、解放できなくなってしまうので、 メモリリークを起こして問題な気がするのですが、実際はどうなのでしょうか? よろしくお願いいたします。

  • 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 確認方法 変数等がヒープかスタック領域のどちらに確保されたかは どうやって見分けることができますか? アドレスの値から判断できますか? よろしくお願い致します。

専門家に質問してみよう