C言語で巨大配列を作るにはどうすれば良いのでしょうか?
テストで作ってみた配列を用いたプログラムが動かなかったので(コンパイルは正常)、なんでだろうと思って調べてみると、巨大な配列はcalloc関数等を用いて作る必要があると知りました。
しかし正直解説サイトを見てもよく意味が分かりませんでした…。
例えばA[1000][1000][1000]の様な配列は、どの様に作ればいいのでしょうか?
A[x][y][z]みたいに表現して、Aを変えて同じ様な配列を8個ほど作りたいです。
初心者なので勉強不足かも知れませんが、どうぞ宜しくお願い致します。
No.5ベストアンサー
- 回答日時:
>計算対象の要素個数は3億個
32bit版Windowsの場合、1プロセスあたりの上限は2GBです。(OS全体でも約3.2GBが上限)
また仮に4GBのメモリーをのせていても、
mallocで1GBのメモリーが確保できるとは限りません。
(連続領域で確保しようとする為)
64bitアプリとして作成するのもひとつの方法ですが、
別の方法として
ファイルIOを使って、処理する事も可能です。
例えばint A[1000][1000][1000]
を扱いたいのであれば
a000、a001、a002・・・というファイルを1000個作成し、
それをメモリに見立てて使う方法があります。
1つのファイルには1000*1000の要素を格納します。
A[500][250][100]にアクセスしたいのなら
a500というファイルの250*100*sizeof(int)+100*sizeof(int)バイト目にシークしてアクセスする
方法です。
No.8
- 回答日時:
再び質問がありましたので再登場させて頂きました。
すみません、自分が提示した方法は、サイト等で見かけたって
事ではないので、解説サイトを提示できないのです。
自分は利用した事がないですが、No.7(gentoo314さん)の
教えて下さったファイルマッピングがいいかもしれませんね。
ただ、言いっ放しでは申し訳ないので、ちょっとだけ
書かせて頂きます。これは、メモリがショボかった時代に
自分が使っていた手法です。
※例を簡略化する為に2次元の小さい配列としています。
※下記のコードはソラで書いているので、間違えてたら
すみません。でもイメージは沸くと思います。
----------------------------------------
もし short sArray[10][4] という配列を想定した場合、
それをbyte配列にすると、
BYTE bArray[80];
となります。(BYTE = unsigned char)
bArray を sArray のように扱う為に、以下の関数を用意します。
// 指定の x, y を元に、byte配列の位置を返す
int GetPos(int x, int y)
{
return(x * 10 + y);
}
// byte配列の指定の位置に値を書き込む
void SetValue(int x, int y, int v)
{
bArray[GetPos(x, y) ] = ( (v & 0xFF00) >> 8);
bArray[GetPos(x, y) + 1] = ( v & 0x00FF );
return;
}
// byte配列の指定の位置から値を読み込む
int GetValue(int x, int y)
{
int v = 0;
v =(bArray[GetPos(x,y) ] << 8);
v+= bArray[GetPos(x,y) + 1];
return(v);
}
後は、
SetValue(1,2, 12345);// 書く
int v = GetValue(1,2);// 読む
みたいな感じで使います。今回の件ではファイルに吐き出す
事になると思うので、GetPos に fseekを組み合わせて、
あとはファイル相手にゴリゴリ処理する……という雰囲気。
全く高度じゃない手法ですが、簡単な事だけが取り柄です(^^;
No.6
- 回答日時:
すいません。
訂正します。>a500というファイルの250*100*sizeof(int)+100*sizeof(int)バイト目にシークしてアクセスする
>方法です。
250*1000*sizeof(int)+100*sizeof(int)
の間違えです。
なるほど…。
なんとなく分かりました…。
軽く調べてみたのですが、http://www.isl.ne.jp/pcsp/beginC/C_Language_16.h … の様な考え方にすればよいのでしょうか?
小さく計算→ファイルに書き出し→必要な時に読み込み→其れを元に計算→上書き。
他の方のアドバイスを含め色々教えて頂けたので、だんだん方向性が見えてきました。
本当にありがとうございます。
No.4
- 回答日時:
ずいぶんメモリを使う処理なんですね(^^;
メモリ上で処理しきれない場合は、一度DBなりファイルなりに
吐き出して、それを処理する形にするしかないと思いますよ。
例を拝見する限りでは、扱いたいのは固定長配列という事
なのですよね?ならばいっその事、単純なbyte配列にして、
後はロジック側で対応するのも一案です。固定長ならば、
その処理も簡単ですので。あえて配列にする必要はないと
思いますし、byte配列の方がファイルに吐き出した時に
扱いが楽……かも? もし自分ならばそう作っちゃいます。
ですが、これだと質問に対する答えでなく代替案ですよね。
もし配列にこだわる必要があるならスミマセン。
ご回答有難うございます。
私が余にも知識不足なので、そんな方法が有るとは知りませんでした…。
確かに無理に配列にする必要はありません。
宜しければ、その辺の方法が紹介されているサイトが有れば教えて頂けないでしょうか。
No.3
- 回答日時:
calloc とか、解説サイト云々以前に、まず
A[1000][1000][1000] で確保されるメモリのサイズがどれくらいかわかりますか?
1キロバイト = 1,024 BYTE
1メガバイト = 1,048,576 BYTE( 1024*1024)
1ギガバイト = 1,073,741,824 BYTE(1024*1024*1024)
Aの型はなんでしょう? int ですか
だとすると、確保したいメモリは、およそ4ギガ
さらにそれを8個程つくるのですから、32ギガ
BYTE型だとしても、およそ1ギガで8個なら8ギガ
それだけのメモリがある事前提での質問でしょうか?
正直、データのサイズの事は分かりませんでした…。
プログラム云々以前に基本的な知識が無かったと思います、勉強不足なのでその辺を勉強してみようと思います。
ご丁寧に有難うございました。
No.2
- 回答日時:
そんな巨大な配列で何をやりたいんでしょうか?
目的と手段を履き違えて、「巨大な配列を作る」こと自体が目的化していませんか?
そのあたりを踏まえて、一度再考した方がいいと思いますけど。
OSが書かれてないので参考程度ですが、32bit版Windowsのアプリケーション領域は4GBなので、たとえばAの型が4byte型だとA一つでほぼその全てを使い切ります。
すいません、その辺何も書いていませんでした。
学習の一環(個人的な)で簡単な熱伝導解析をPCにやらせてみたいと思った次第です…。
計算対象の要素個数は3億個ほどです、単純に出来るんじゃないかな?と気軽に考えていましたが、やっぱり大容量な問題もあり難しい事なんですね…。
一度良く考えてみます。
有難うございました。
No.1
- 回答日時:
>例えばA[1000][1000][1000]の様な配列は
charの配列だとしても、1000×1000×1000ですから約1GByte、
intの配列であれば約4GByteですから32BitOSでは無理です。
64BitOSだとしても、スワップしまくりで動作がかなり遅くなりそうです。
設計からみなおしたほうがいいでしょう。
有難うございます。
なるほどやはりサイズが大きすぎなのですね… 計算を小さくして何とか試してみたいと思います。
ちなみに配列で表現できる大きさはどの程度が限界なのでしょうか?
また変数として(データ)として保持できるサイズはどれぐらいでしょうか?
宜しくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- Excel(エクセル) ExcelVBAでリストの項目に必要数と同じ手配数を分配していくマクロを作りたいです。 1 2022/07/29 18:36
- その他(プログラミング・Web制作) プログラミングについて(Python) 添付した画像はC言語で簡単に作ったソースで、1つの配列に5つ 3 2022/09/10 19:15
- PHP 配列の値の更新方法について 1 2022/08/05 09:49
- Ruby 初心者プログラミング 3 2022/10/12 11:31
- Perl perlで2次元配列をサブルーチンに値渡しで渡す 5 2022/12/17 18:49
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# C#の問題です。 文字列型の配列 s[100] にキーボードから入力された100文字以内の文字列(単 2 2022/06/22 15:18
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語 配列の長さの上限
-
テキストファイルから文字列を...
-
配列を使わずに、変数名を動的...
-
C++ vectorに配列をプッシュしたい
-
先頭アドレスとは何ですか?
-
ExcelVBAで質問です。離れた二...
-
配列の参照渡しで型が一致しま...
-
VBで構造体の配列を関数に渡す...
-
unsigned char配列への入力の仕方
-
配列内の文字間を排他的論理和...
-
配列で格納したものをmsgboxで...
-
Excel、VBAのユーザーフォーム...
-
C# Listを使わずに2次元配列の...
-
配列を含む構造体の初期値について
-
C言語で特定列だけを抽出して配...
-
配列をEraseしてもメモリが開放...
-
if文で「配列a[i]が小数ならば...
-
c言語乱数について
-
unsigned char の配列で途中で0...
-
accessVB メモリ不足でDiskでで...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語 配列の長さの上限
-
配列を使わずに、変数名を動的...
-
先頭アドレスとは何ですか?
-
配列で格納したものをmsgboxで...
-
C# 配列の変数宣言について。
-
テキストファイルから文字列を...
-
unsigned char配列への入力の仕方
-
ExcelVBAで質問です。離れた二...
-
配列の参照渡しで型が一致しま...
-
パイソンの
-
C# Listを使わずに2次元配列の...
-
C言語で特定列だけを抽出して配...
-
複数の選択範囲の行番号を個別...
-
【C言語】配列の中に配列を入れ...
-
メモリの初期値
-
VBで構造体の配列を関数に渡す...
-
Excel、VBAのユーザーフォーム...
-
配列をEraseしてもメモリが開放...
-
2次元配列を戻り値とする関数?
-
【速いブラインドタッチ】手を...
おすすめ情報