• ベストアンサー

グローバル変数とメモリについて

質問させてもらいます。 #include <stdio.h> #include <math.h> #include M 1000 double a[M][M]; のようにプログラム冒頭にグローバル変数として配列aを宣言しているのですが、windowsXPではMを4096以上にして保存し、コンパイル(BCC)すると Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland beki4.c: Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland Fatal: Error detected (LME1514) Fatal: Error detected (LME1514) Fatal: Error detected (LME1514) Fatal: Error detected (LME1514) と出て、コンパイルができません。4095では可能でした。 最初はメモリの不足かと思ったのですが、単純に計算すると4096*4096*8 byteで、この配列には約134MB程度しかかかりません。メインメモリが1GBでその他OSなどが消費しているメモリは500MB程度なのでメモリ不足では無いような気がします。 同じプログラムをfedora8でメインメモリ1GBのPCでやらせてみた所、M=16383まではコンパイル(gcc)でき、16384以上では「too large」と言われてコンパイルできませんでした。 それぞれのOSでのMの設定値の限界が4095(=2^12-1),16383(=2^14-1)となっていまして、これはそれぞれのOSで一つの変数が占有できるメモリの限界を定めているということを意味しているのでしょうか? またこのような限度がOSにあった場合、その設定を変更する方法はありますか? よろしくお願いします。 実際のプログラム→http://cocofox.konjiki.jp/beki.html(文字数制限の関係上ここにすべてのcodeを記載できないため)

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

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.4

★アドバイス ・Windows では仮想メモリの上限が2ギガ・バイトまでです。  でも実際には物理メモリ量やスタックその他で2ギガ・バイトは使えません。  こちらの環境では M=4096 はもちろん M=16367 までコンパイルできました。  ただし M=16367 では実行時にエラーになりました。  (物理メモリが足りないので当然ですが…) ・こちらの環境は Windows XP Home SP2、RAM=768MB です。  コンパイラは VC++2003.NET でコンソール・アプリケーションとして試しました。  M=4096 まではコンパイル、実行時のエラーもありませんでした。 >単純に計算すると4096*4096*8 byteで、この配列には約134MB程度しかかかりません。  ↑  計算が間違っています。  4096*4096*8=134,217,728=128MBです。  ※1024 で割りましょう。  BCCは使ったことがありませんが、もしかしたらコンパイラの設定の違いでしょうか? ・以上。

mac-dows
質問者

お礼

ご回答ありがとうございます。たしかに1000でなく1024で割るべきでした、指摘ありがとうございます。

その他の回答 (5)

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

何となくリンカの問題のような気がします。 というのも、M=4096ではエラーが発生しますが.exeは生成され、実行もできます。M=5287まではそうした状況が続きます。M=5288以上になると.exeが生成されなくなり、エラーメッセージがおかしくなります。 M=5709以上になると、 Fatal: Out of memory というエラーメッセージに変わります。 一応C90で保証されるオブジェクトのバイト数は32767バイトまでですので、Mが大きくなると規格上は保証がなくなります。結果として未定義の動作に至ったとしても、一概にリンカの不具合とまではいえません。 ただ、不親切なことは確かですね。

mac-dows
質問者

お礼

回答ありがとうございます。 返答に時間がかかってしまい申し訳ありませんでした。 現状の結果としては質問しました問題は解決できていないのですが、別の形で十分な量の実験データをとることができましたので、これで今回は質問を閉じたいと思います。アドバイスを下さった皆様、本当にありがとうございました。

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.5

★追記。 ・VirtualAlloc() 関数を使ったらどのぐらい確保できますか?  下のサンプルでは 128 MBのメモリを確保します。  試して見て下さい。  (もし、確保できればコンパイラの設定か、コンパイラが原因かもしれない) #include <stdio.h> #include <windows.h> // メイン関数 int main( void ) {  SIZE_T dwSize = 128 * 1024 * 1024;  // 128MB  LPTSTR lpBuff;    if ( (lpBuff = (LPTSTR)VirtualAlloc(NULL,dwSize,MEM_COMMIT,PAGE_READWRITE | PAGE_NOCACHE)) != NULL ){   ZeroMemory( lpBuff, dwSize );   VirtualFree( lpBuff, dwSize, MEM_RELEASE );  }  return 0; }

mac-dows
質問者

補足

ありがとうございます。頂いたサンプルですが正直ぜんぜん内容が分からないので、何をもってメモリが確保できたとわかるのか分からないのですが、実行することはできました。加えて、タスクマネージャを使ってメモリの消費を見ていると、実行した瞬間に120MBくらい消費が増加するのが確認できました。(一瞬なので細かい増加量はわかりませんorz) 確保できたとなるとやはりコンパイラの設定が問題なのかもしれません。

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.3

>グローバル変数 そですね。。。スタティック領域なので、 スタックは関係なさそうですorz

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

グローバル変数ですのでスタック領域ではなくてデータセグメント(明示的な初期化が無いのでBSS)の大きさの制限だとおもいます。 手元にBCCが無いので確認できないのですが、コンパイラの設定で拡大できると思います。 OSの制限なら、リンクは成功して実行するときにエラーになっているはずです。

mac-dows
質問者

お礼

ご回答ありがとうございます。OSではなくコンパイラの設定の問題ですか、helpなどになにかないか見てみます。

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.1

>またこのような限度がOSにあった場合、 >その設定を変更する方法はありますか? OSではなくコンパイラにスタックサイズの制限があります。 BCC/VCなどはデフォルト1Mくらいだったかと。 32Bit環境としてdouble=8バイト 8*1000*1000バイトでオーバーですね。 過去ログ http://oshiete1.goo.ne.jp/qa2487531.html

mac-dows
質問者

お礼

ご回答ありがとうございます。リンク先参考になりました。

関連するQ&A

  • Borland C++ Compiler で winbase.h を使えないのですが・・・

    Borland C++ Compiler を使っているのですが,winbase.h 自体が使用できません。 次のようなプログラムでもコンパイルが通りません。 #include <winbase.h> int main(void){ return 0; } エラーは以下の通りです。 *** コンパイル開始 *** Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland ########.c: エラー E2139 C:\borland\bcc55\Include\winbase.h 227: 宣言に ; がない エラー E2238 C:\borland\bcc55\Include\winbase.h 228: 'ULONG_PTR' の宣言が複数見つかった エラー E2344 C:\borland\bcc55\Include\winbase.h 227: 一つ前の 'ULONG_PTR' の定義位置 (中略) エラー E2228 C:\borland\bcc55\Include\winbase.h 263: エラーあるいは警告が多すぎる *** 26 errors in Compile *** *** コンパイル終了 *** どうすればよいでしょうか? 何かちょっとした情報でもお願いします。

  • Borland C++5.51で

    8MB超のソース junk.cpp を bcc32 -I"c:\Borland\Bcc55\include" -L"c:\Borland\Bcc55\lib" -W -WM -VM junk としてコンパイルしようとしたら Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland junk.cpp: Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland Fatal: Error detected (IMP302) Fatal: となりエラーになりました 8MBを切れば大丈夫だったのです IMP302とerrorで検索すると 外国に同じ問題でメーリングリストに質問しているものがあったのですが回答が得られていません 本人はリンク時エラーなのでソース分割すれば通る事は通るといっていました 分割が大変なソースなのでこのエラーをクリアしたいのですが解決策は無いのでしょうか?

  • condefs.hはどこにあるの?

    #include <stdio.h> #include <windows.h> #ifdef __BORLANDC__ #include <condefs.h> #endif をヘッダに含むプログラムspitest.cppを無償コンパイラのボーランドC++5.5でコンパイルすると Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland spitest.cpp: エラー E2209 spitest.cpp 8: インクルードファイル 'condefs.h' をオープンできない *** 1 errors in Compile *** とエラーがでました。 どうしたらいいのでしょうか?

  • コンパイルエラー

    本日からC++を勉強しはじめました。 使用しているコンパイラはBORLAND C++ COMPILER 5.5 です。 #include<iostream> int main(){ cout<<"hello"; return 0; } 上記をコンパイルすると下記のエラーが出ます。 いったいどこがいけないのでしょうか。 どなたか教えてくださいませ。 Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland 123.c: 致命的エラー F1003 C:\BORLAND\BCC55\include\stdcomp.h 5: error 指令: Must use C++ for STDCOMP.H *** 1 errors in Compile *** *** コンパイル終了 ***

  • BorlandC++5.5言語の環境変数変数の設定方法を教えて下さい。

    環境変数で質問があります。Bortland5.5の環境変数の設定方法を教えて下さい。 今までJavaとtomcatをDLしました。これらPathという名前で設定してきました。 Bortland5.5もPathで設定すればいいようですがどう設定していいのかよくわかりません。 私は「BCC」という名前で設定してみました。 是非に環境変数の設定方法を教えて下さい。 今回C++言語であるBortlandをDLしました。 ダウンロード先はprogram files です。先ほど見たところBinというファイルが DLされてました。環境変数の設定で BCC55をDLしたので「システム環境変数をBCC=C:\Program Files\Bin」 としてユーザー環境変数を「C:\Program Files\Java\jdk1.5.0_05\bin;%CATALINA_HOME%;\bin;%BCC%」 と入力したところエラーが表示されます。 「Hello.c」というファイルを作成しコンパイルすると以下のエラーが出ます。 ーーーーーーーーーーーーーーーーーーーーーーーー c:\october>bcc32 Hello.c Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland hello.c: エラー E2209 hello.c 1: インクルードファイル 'stdio.h' をオープンできない 警告 W8065 hello.c 4: プロトタイプ宣言のない関数 'printf' の呼び出し(関数 main ) 警告 W8070 hello.c 6: 関数は値を返すべき(関数 main ) *** 1 errors in Compile *** 実行するとエラーがでます。 c:\october>Hello 'Hello' は、内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチ ファイルとして認識されていません。 と表示されます。 なお作成したファイルは以下のC言語です。ファイル名「Hello.c」 #include <stdio.h> main() { printf("Hello, C Program!\n"); }

  • Cコンパイラーのついてのご質問です。

    Cの勉強をしようとして、 MS-DOSを開いて、 bcc32 sample11.cといれてコンパイルをしようとしたんですが、『 C:\source>bcc32 sample11.c Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland sample11.c: Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland Fatal: ファイル C0X32.OBJ が開けません C:\source>    』のようにでてきましたどうすれば良いのでしょうか?教えてください。 (ちなみに、今回のプログラムは #include <stdio.h> main() { printf("Hello!"); return 0; } です初めてのプログラムなので簡単です。)初めてプログラミングを勉強するので、できれば、詳しくお願いします。

  • PathIsDirectoryを使って

    #include <windows.h> #include <stdio.h> //#include <Dbghelp.h> #include <shlwapi.h> void main(void) { char *Path = "c:\\windows\\system32\\"; if(PathIsDirectory(Path)) printf("'%s'は正しいディレクトリである。\n",Path); else printf("'%s'は正しいディレクトリでない。\n",Path); } をボーランドC++5.5でコンパイルすると Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland test.cpp: Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland Error: 外部シンボル 'PathIsDirectoryA' が未解決(C:\BORLAND\test.OBJ が参照) というエラーがでました。 どうしたらいいのでしょうか?

  • Borland C++ Compiler

    学校のC言語の授業で使用するので、Borland C++ Compilerをインストールしました。 今までに作ったプログラムや、教科書に載っていたサンプルプログラムをコンパイルして軽い勉強をしていたのですが、コンパイルの際にエラーが出るようになりました。 コマンドプロンプトでbcc32と打つと、パラメータのリストのようなものが出てくるので、-nなど適当にパラメータをつけて実行したら以下のようなエラーが出るようになりました。 Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland test.c: Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland Error: 外部シンボル '_main' が未解決(C:\BORLAND\BCC55\LIB\C0X32.OBJ が参照) objとtdsファイルは出力されるのですが、exeが出力されません。 どうやったらなおるか、教えてください。

  • 一次元配列についての質問です。

    配列matを以下の様に宣言し、要素の値が2の倍数、または3の倍数ならば、その添え字を書き出すプログラムを作成しています。が、下記にある様にエラーがあるらしく、コンパイル出来ません。色々といじくっているのですが、どこが悪いのか見当もつきません。解る方、教えて下さい。あと、このプログラム、此処が間違っているよ、というのがありましたら、教えて下さい。 宜しくお願いします。 #include <stdio.h> int main(void) { int i,mat[10]={5,3,8,2,7,1,10,4,9,6}; for(i=0;i<10;i++) { if(mat[i]% 2==0 || mat[i]% 3==0){  printf("%d",i); } } printf("\n"); return(0); } cmd.exe /C bcc32.EXE "3と2の倍数.c" ------ コンパイル開始 ------ Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland 3と2の倍数.c: エラー E2206 3と2の倍数.c 7: 不正な文字 ' ' (0x8140)(関数 main ) *** 1 errors in Compile *** ------ コンパイル終了 ------

  • 一番最初でつまずいてます!!

    Borland C++Compilerをインストールしてプログラミングの勉強をし始めたばかりです。 #include<stdio.h> int main(void) { printf("はじめてのC言語プログラム"); return 0; } と入力してコンパイルすると 「インクルードファイル'stdio.h'をオープンできない」 というエラーがでました。 何度も見直したし、環境変数も合わせてるのになぜでしょうか!?

専門家に質問してみよう