- ベストアンサー
グローバル変数のサイズ
C言語でWindowsのプログラムを作成しようとしています。(初心者) Windows のプログラムでは、グローバル変数は最大どれくらい確保できるものなのでしょうか? また、グローバル変数を多く取りすぎると、OSへ影響が出るのでしょうか? 下記の変数を確保使用としています。 char Data[1000][4096]; よろしくお願いいたします。
- みんなの回答 (14)
- 専門家の回答
質問者が選んだベストアンサー
> 私は、組込みは少し経験があったのですが、 > Windowsプログラムは経験がなくメモリの扱い方や > 制限が気になっていました。 組み込みシステムとは違って、PCのプログラムは「富豪的プログラミング」なんてのがあるぐらいなので、メモリはそれほど気にしなくてもいいです。 わたしは個人的には富豪的プログラミングには全面的に賛同できないんですが… 富豪的プログラミングについては以下 http://pitecan.com/fugo.html エコプログラミングなるものを提唱しているひとも。 http://nais.to/~yto/doc/zb/0017.html > 私としては、メモリ確保のオーバヘッドや初期化処理等に > 時間がかかるのかなとか、なんらかのデータ構造の > アルゴリズムをした際の検索に時間がかかるのかなとか > 思っていました。 オーバヘッドや初期化処理は静的に確保しても対して変わりません。プログラムのロード時に実際のところ初期化するのですから。staticに確保すると通常は0で埋められますが、プログラムをロードする際に0でクリアしています。それをプログラムで明示的に行うだけですし、現在のPC用のOSはメモリを確保しても初期化したり、データを入れるまでは実際にはメモリを割り付けていないケースが多いです。 # ディスクからデータを読み込む場合、オンデマンドで # 割り付けてもディスクI/Oの待ち時間に十分処理できたり。
その他の回答 (13)
- jikenjp
- ベストアンサー率38% (5/13)
小学生に、円周率を、 "3.14" と教えるべきか、 "3" と教えるべきか?? マイクロソフト↓
- rentahero
- ベストアンサー率53% (182/342)
> 『char Data[1000][4096];』を使用しインデックスで、 > 読出し,書込みを高速に行おうとしています。 > このような使い方の場合、mallocを使用すると、 > 検索に時間がかかってしまいそうな気がしますが、 > いい方法はないでしょうか? 何の検索でしょうか。 mallocに時間がかかると思ったのはどうしてですか。 速度を追求したいのであれば、こんなのもできます。 #include <stdio.h> #include <stdlib.h> #define d1MAX (1000) #define d2MAX (4096) #define Data(d1, d2) (buf[d2MAX * (d1) + (d2)]) // マクロでフラットな配列に展開 int main() { char *buf; buf=(char *)malloc(d1MAX * d2MAX); // mallocで一括確保 memset(buf, 0, d1MAX * d2MAX); // staticと等価にするため一応クリアしておく Data(20, 30) = 100; printf("%d\n", Data(20,30)); return 0; } これならそれほど違和感ないんじゃないかな。 実際のところ、メモリのアクセスを高速化するよりディスクへのI/Oを減らすことの方がずっと高速化には寄与しますね。 ちなみに、ファイルの読み込みを例にして fread(Data[10], 1, 4096, fp); いう風にしようと思っていたのであれば、 fread(&Data(10,0), 1, 4096, fp); として代用できます。 心配なら、&(Data(10,0))としてもいいでしょう。&((buf[(4096)*(10)+(0)]))と展開されるので、括弧はひとつ無駄になりますが、たいした問題ではありません。
お礼
回答ありがとうございます。 > 『char Data[1000][4096];』を使用しインデックスで、読出し,書込みを高速に行おうとしています。・・・・ について言葉が足りませんでした。申し訳ありません。 私としては、メモリ確保のオーバヘッドや初期化処理等に時間がかかるのかなとか、なんらかのデータ構造のアルゴリズムをした際の検索に時間がかかるのかなとか思っていました。 どちらにしても、今のPCであれば、たいした時間ではなかったですね。
- rentahero
- ベストアンサー率53% (182/342)
> Windows のプログラムでは、グローバル変数は > 最大どれくらい確保できるものなのでしょうか? グローバル変数というのが スタティックでコンパイル時に確保されるものを指しているのであれば、プログラムが起動するのに必要なメモリが確保できればそれで起動可能。 ヒープにmallocで確保するものを指しているのであれば、ヒープに空きがある分(32ビットwindowsなら2G以下だったかな) > また、グローバル変数を多く取りすぎると、 > OSへ影響が出るのでしょうか? スタティックな方であれば、単にそのプログラムが起動できないか、他のプログラムが起動できなくなるだけです。OSが文句を言えば、そのプログラムを終了すればすぐに復帰するでしょう。 mallocで確保する方であれば、限界までとると他のプログラムが起動できなくなるでしょう。こちらもプログラムを終了すると多分復帰できると思います。 > 下記の変数を確保使用としています。 > char Data[1000][4096]; 今のPCなら、4MBでは多分なんてことはないでしょう。 #明示的な回答者に向けての回答は削除対象だったはずでは…。
お礼
回答ありがとうございました。 私は、組込みは少し経験があったのですが、Windowsプログラムは経験がなくメモリの扱い方や制限が気になっていました。 >今のPCなら、4MBでは多分なんてことはないでしょう。 を聞いて勉強になりました。 ありがとうございました
- jikenjp
- ベストアンサー率38% (5/13)
>ency さま。 "c" "c++" どちらで組んでも、大切な事は、デバッガが、使い易いかどうかがとても大切のように思います。 それがしは、以前、"HP の xdb" 今は、Fedora Core 3 (GNOME) がとても使い安く、愛用してますが、"ency" 樣は、いかがですか? >Tacosan さま。 "c" 出組まれた、とても移植性の高い、優れたプログラム、"Windows95" "Windows98" (IBM のワークステーションも) Cコンパイラ、どうにもなりませんでしたが、これを、"仕様" あるいは "障害" と見るかは、その人の判断しだいと思われますが、>Tacosan さまは、どうおもいますか??
- ency
- ベストアンサー率39% (93/238)
私だったら、インデックスとデータを組にした構造体を定義して、必要な分だけ構造体サイズ分 malloc() しますね。 # C++ や Java だったら、クラスを定義してインスタンスを…と同じことですね。 で、データを探索する必要があるのであれば、たとえばリスト構造のような形にして、データはインデックスでソートしておけば、何とかなるかなぁ…と。。。
- Tacosan
- ベストアンサー率23% (3656/15482)
疎なデータだったら「添字」と「その添字に対応するデータ」の組を記憶するって方法もあるんですけどね.... 密だと malloc 使うのが普通かなぁ. malloc に関していえば, 確か Linux は 1プロセスでメモリを使い果たさない限りメモリを確保したことにしちゃうはず>#7. OS の「障害」とかじゃなくって「仕様」です, 「仕様」.
- jikenjp
- ベストアンサー率38% (5/13)
>pokoさんへ。早速のご返事、ありがとねー。 いろいろ、やりかたあると思いますが、なんでも奇抜な冒険も無駄には、ならないと思います。 ちなみに、それがし、メインメモリ"32GB"(ふつ~のパソコンの64倍)を想定した、プログラミングしているのですが、"Linux Fedora Core 3" の "OS" 、"malloc" に障害あって、メモリ確保に失敗しても、"NULL" 戻ってきてくれないら! 今度は、それがしの質問にも、暇な時、ご返事いただけたら、感激です。 では。
- suzukika
- ベストアンサー率28% (8/28)
補足ですが、一旦ポインタがmallocによりメモリを確保されたら、配列遣い可能になります。 eg. #include <stdlib.h> char *p; p=(char *)malloc(32); p[10]='a'; free(p);
お礼
回答ありがとうございます。 ほぼ同時刻に「ANo.5」さんと同じ回答を頂いたみたいですね。 皆さんの回答通り、mallocを使用したほうがOSには負担にならないようですね。 サンプルプログラム参考にさせていただきます。
- jikenjp
- ベストアンサー率38% (5/13)
こんにちは。こんごとも、よろしくね。最近この "OKWave" サン知りました。 たぶん、わたしだったら、下記のように、すると思いますが、もっといい方法あるかもしれません。(スペース入れ方、分らないので、"_" いれてます。 #define Y_MAX 1000 #define X_MAX 4096 char *Data[Y_MAX]; /* extern */ main(){ __int i,j; __for(i=0; i < Y_MAX; i++){ ____Data[i] = (char *) malloc(sizeof(char) * X_MAX); ____if(Data[i] == NULL) exit(-1); /* error ハンドリングしてねー */ ____else{ ______for(j=0; j < X_MAX; j++){ ________Data[i][j] = 0; /* bit clear */ ______} ____} __} __Data[i] = NULL; }
補足
回答ありがとうございます。 なるほど、この方法であればグローバル変数のサイズは、『Y_MAX』になりますね。 やはり皆さんの回答通り、mallocを使用したほうがOSには負担にならないのでしょうか?
- suzukika
- ベストアンサー率28% (8/28)
>『char Data[1000][4096];』を使用しインデックスで、読出し,書込みを高速に行おうとしています。このような使い方の場合、mallocを使用すると、検索に時間がかかってしまいそうな気がしますが、いい方法はないでしょうか? ------------------- この問題については、本来配列の添字による走査は便利ですが、ポインタによる配列の走査が速いと思います。 自分は下記のような配列の走査がよく使います: /* put a NULL as a member of array , For judging pointer */ char *str[] = { "aaa". "bbb", NULL}; char **pointer = NULL; pointer = str; while(*pointer){/* 最後のNULLになったら終了 */ dosomething();/* 処理 */ pointer++; } なお、添字みたいなメンバーへアクセスするとき、pointer+nでアクセス可能だと思います。 もちろん、ポインタ使わず、配列だけ使っても結構です。
補足
早速の回答ありがとうございました。 私の補足質問に言葉か足らなかったようです。申し訳ありませんでした。 データが固定である場合、『char *str[] = { "aaa", "bbb", NULL};』も可能かと私も考えましたが、格納すべき入力データは、インデックスごとにどランダムに入力され、このデータを『char Data[1000][4096];』に格納しようとしています。また、扱うデータはバイナリデータです。 検索に多少時間がかかっても、mallocを使用した何らかのデータ構造を使用したほうがいいとゆうことででしょうか?
- 1
- 2
お礼
いろいろ詳しく教えていただきありがとうございました。 教えていただいたURLで、もう少し勉強していこうと思います。