• ベストアンサー

C言語 配列の長さの上限

C言語で配列Array[N]の長さNの上限っていくらなんでしょうか? もし可能なのであれば上限を2147483647にしたいのですが、方法を教えてください。

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

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

そもそもWindowsの32bit版はアプリが仮想メモリ空間を2GBしか使えません。2GBを超えるには64bit版が必要です。 たとえ64bit版OSだとしても添え字が2147483647って、単純なintの配列だとしても4x2147483647=8GB必要ですね。実メモリ16GBとかのPCを用意しますか? そもそも配列で2147483647個必要なアルゴリズムに問題ありだと思います。

phyedu
質問者

お礼

8GBとはエラーが出るはずです。 ありがとうございました。

その他の回答 (6)

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

規格上、1個のオブジェクトのバイト数として保証されるのは... C90の場合、32767バイトまで C99の場合、65535バイトまで です。 バイト数ですので、配列の要素がint型であれば、(C90なら)32767/sizeof(int)バイトまでです。

  • buriburi3
  • ベストアンサー率44% (353/792)
回答No.6

(私の経験では)添え字の中は符号付のint型で解釈されるのでアクセスできるのはint型の正の最大値まで。 ※添え字で参照できないだけで、ポインタ使ったり多次元配列とのUNIONにしたり工夫すれば使用は可能 他の方の回答にあるように、確保出来る配列サイズの最大は別問題

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.5

あなたの環境が全く分からないので具体的な上限は書けませんが, 規格上ホステッド環境 (端的には「OS の上で動いている状態」) では「65536 バイト以上のオブジェクトは使えなくても文句は言えない」となっています. つまり, sizeof Array ≧ 65536 となるときには動かないかもしれません. おまけですが「そもそもWindowsの32bit版はアプリが仮想メモリ空間を2GBしか使えません。2GBを超えるには64bit版が必要です。」というのは正確じゃないですね>#2. 仮想メモリ空間そのものはちゃんと 4GB とられています. ただしカーネルが使うメモリ分として 2GB (オプションを付ければ 1GB) 持っていかれるので, 「ユーザプログラムが自由に使える領域」として 2GB (または 3GB) の制限があります... という説明も本当は正確じゃない (1プロセスでそれを超えるメモリを使う技術は存在する) んだが, 面倒なので以下省略. とはいえ, こんなことができるかどうかを考える前に, どうしてそんなにメモリが必要なのかを検討するべきだというこれまでの回答者の意見には全面的に賛成.

  • chie65535
  • ベストアンサー率43% (8514/19356)
回答No.4

>C言語で配列Array[N]の長さNの上限っていくらなんでしょうか? 言語仕様上では、上限はありません。 コンパイラは「実行時に実際にメモリが確保出来るかどうかは考えず、言われた通りに、言われた通りの領域を確保するようなプログラムコードを生成するだけ」です。 リンクして実行ファイルを作ろうとした時にサイズオーバーしてエラーになろうが、実行時にスタックやデータ領域が足りずに例外を発生して異常終了しようが、コンパイラは「お構いなし」です。 ただ黙々と「言われた通りにコード生成」して「後の事は知ったこっちゃない」のが「コンパイラ」です。 そして「後の事は知ったこっちゃない状態」で作られたプログラムは、実行したとたん「メモリが破綻して異常終了」するでしょう。 >もし可能なのであれば上限を2147483647にしたいのですが それは「要素数が2147483647個の配列を作りたい」って事ですか? だとしたら「その配列が確保出来る実行環境」を用意し、そこで実行すれば良いだけです。 例えば「64ビットCPUを搭載し、64ビットのアドレス空間すべてにメモリを実装してあって、64ビットのアドレス空間を自在に使用可能なOSを走らせ、そのOSで動く実行ファイルを生成するコンパイラ」を使えば、要素数が2147483647個の配列を何個でも使えます。 なぜなら、その動作環境では「メモリが18446744073709551616バイトもある」のですから「要素数が2147483647個の配列なんか、ゴミみたいなもん」です。 このように「実行環境で、メモリが無尽蔵にある」かも知れないので「コンパイラは、言語仕様上では、配列の要素数に上限を設けていない」のです。 下手に、仕様に「上限」を定めてしまうと「実行環境では充分なメモリがあるのに、言語の仕様に縛られて、大きな配列を確保出来なくなってしまう」という弊害が出ます。なので「仕様では、上限無し」になっています。 もちろん、それは「仕様の上だけ」であって「実行時、実際に、そんだけのメモリが確保出来るかは、まったく別の問題」です。

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.3

私が今ままで、プログラミングをしてきた経験では、 そのような、非常に大きい添え字を必要とする状況は発生しませんでした。 通常、そこまでの添え字を必要としないと思いますが、 どうしてそのようなことをなさりたいのでしょうか? そのこと自体に、非常に興味があります。 よろしければ、その理由もしくは背景を教えていただけませんでしょうか?

phyedu
質問者

補足

物理系のシミュレーションをしています。 試行ごとにある現象が起こるかどうかをrand()%RAND_MAXがその現象が起こる確率pに比べて大きいか小さいかで判断しています。 この方法では毎回rand()を参照しなければならずボトルネックになっていました。そこで、あらかじめArray[0]~Array[RAND_MAX-1]まで乱数を読み込んでおいて順番に使おうかなと考えました。 そのためにArray[RAND_MAX] (RAND_MAX=2147483647)の配列を準備したかったというのが背景です。 しかし、先ほど自分でもいろいろと調べていたらxorshift()という関数が非常に高速でかつ乱数としても優れているそうなのでそちらを使ってみることにしました。xorshift()に関しては分からないことがありますが、それは別の質問とします。

  • i-kujou
  • ベストアンサー率50% (13/26)
回答No.1

言語上の上限はsize_tの上限と一致するとは思いますが、そんなメモリをスタックに保有できるような環境は存在しません。 Windows上では一般的にスタックは1Mとかですから、実質的にはその半分の500kも確保できれば良いほうじゃないんでしょうか? C言語で長大な配列を確保したい場合は、動的配列にするのが常套手段ですが、それでも2Gなんて連続領域を確保することはほぼ不可能だと思います。

関連するQ&A

  • C++言語の配列の呼び方,動的・可変長の違い

    C++言語での配列の名称についての質問です. int Array[10]; みたいに宣言する普通の配列は「静的配列」と呼びますよね.コンパイル時に定数で要素数を指定しておかなければならないからですよね. これに対して,new[]演算子を用いて int *Array = new int[n]; といったように確保する配列はなんと呼ばれるのでしょうか. 実行後に変数を用いてその要素数を動的に指定できるので,「動的配列」と呼ぶ人が周りには多いです(「ポインタ配列」とも).しかし,C言語でのrealloc関数みたいに,直接に配列長を変化させるといったようなことはできませんよね. (改めてnew[]してmemcpy()すれば出来るのでしょうが) そこで,配列長をプログラム中で自在に変化させる方法としてstd::vectorを利用する方法がありますよね.このvectorを「動的配列」と呼ぶ人もいました. 私は,new[]したものは動的に要素数を指定できるがその後の配列長は固定であり,vectorはいつでも配列長が可変なので int Array[10]; ・・・静的固定長配列(静的配列) int n = 10; int *Array = new[n]; ・・・動的固定長配列 std::vector<int> v; ・・・可変長配列 と呼んでいるのですが,一般的にはそれぞれどのように呼ばれるのでしょうか. また,最近はstd::arrayをいうものを知りました.これについてもどのように呼ばれるのか,教えてください. よろしくお願いいたします.

  • 【PHP】配列を連想配列に

    $m = array('a', 'b', 'c'); この配列 $m をもとに $n = array(  'a' => array(   'b' => array(    'c' => array()))); 上のような連想配列 $n をつくりたいのですが、 $n = array(  $m[0] => array(   $m[1] => array(    $m[2] => array()))); 要素の数が固定のときは、これでもいいのですが、数が変動する場合に対応できません。 何か方法があれば教えてください。

    • ベストアンサー
    • PHP
  • C言語の2次元配列における行・列指定

    C言語初心者ですがよろしくお願いします。 C言語では、例えばint型の3行4列の2次元配列を表現するときに、 int array[3][4]; とするようですが、 必ず1つ目の[ ]で行番号を、2つ目の[ ]で列番号を表さなければならないものなのでしょうか。 もし慣習的にそうしているものなら、 行と列を指定する[ ]を入れ替えてプログラムを作成しても問題ないのでしょうか? というのも、メモリ上の割り当てが、 array[0][0] array[0][1] array[0][2] array[0][3] array[1][0] array[1][1] array[1][2] ... ... ... array[2][2] array[2][3] のようになるなら、 その配列をfwrite関数でバイナリデータに書きこんで、再度、列方向に読み込みたい時に、 あらかじめ書きこむ前のデータをarray[列][行]の形で扱っていった方が便利ではないかと思ったのですが、なにか初歩的な勘違いしてたりしますでしょうか? ご教授お願いします。

  • C言語配列

    c言語初心者ですよろしくお願いします。 ファイルから読み込んだ100万件のデータをstaticを使わずに配列に格納したいのですが。 どういった方法があるでしょうか? 私のpcでは変数名[10000]くらいがエラーのでない限界みたいです。

  • C言語

    C言語 10進数n(0<n<256)を2進に変換させろ 配列を使うな do-whileでnを入力させることはできましたが、そこから先がわかりません。 for文を使えと言われたのですが……

  • C言語で巨大配列を作るにはどうすれば良いのでしょうか?

    C言語で巨大配列を作るにはどうすれば良いのでしょうか? テストで作ってみた配列を用いたプログラムが動かなかったので(コンパイルは正常)、なんでだろうと思って調べてみると、巨大な配列はcalloc関数等を用いて作る必要があると知りました。 しかし正直解説サイトを見てもよく意味が分かりませんでした…。 例えばA[1000][1000][1000]の様な配列は、どの様に作ればいいのでしょうか? A[x][y][z]みたいに表現して、Aを変えて同じ様な配列を8個ほど作りたいです。 初心者なので勉強不足かも知れませんが、どうぞ宜しくお願い致します。

  • c言語配列拡張

    c言語配列拡張 20個の要素からなる実数配列 x[ ] から、小さい添え字からn個の要素までの 最大値を取り出すプログラムを作成する。計算する要素の数nはキーボード から入力するか乱数で決定するかは乱数により得る。 a. 乱数が奇数の場合はキーボードから入力する。 b.乱数が偶数の場合この乱数の数を用いる。 誰が知ったら教えてください!

  • C言語 配列を交えた関数

    C言語にて配列を絡めた関数を作っています 配列には後にそれぞれの値を与えるのですが double total(int n){ int i; double total = 0; int y[NUMBER] ={0}; for (i = 0 ; i < n ; i++) { tota = tota + (combination(n,i) * power(i) * y[n - i]);} return (tota); } combinationは順列nCi powerは-1^iを表してあり 別々に表示させた場合問題なく出力されます printf("%lf\n" , res + combination(1,0) * power(0) * y[1] + combination(1,1) \ * power(1) * y[0] のようにして実行した場合もただしくでます しかしこれだとtotalを出力させたとき0となり(関数内で配列を初期化させているため?)={0}を消すと出力時に恐ろしい桁の数になってしまいます この関数をうまく作動させるための改善案をご指導願えませんか?情報不足で判断できない場合補足にて追加させていただきます 当方C言語初心者のため詳しくお願いいたします

  • C言語 ポインタと配列

    C言語で配列をあつかう場合、ポインタをつかうか、配列の添え字を使って処理するか迷うのですが、どちらが良いのでしょうか? 処理速度ではどちらが上でしょうか?

  • C言語 行列 配列

    現在、C言語を勉強中です。 C言語で (10000*10000)の大きさの行列を扱いたいです。 double a[10000][10000]の配列ではメモリ不足となってしまいます。 このような場合はどのようにプログラムを組んでいったら良いのでしょうか?

専門家に質問してみよう