教えて!gooにおける不適切な投稿への対応について

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

テストで作ってみた配列を用いたプログラムが動かなかったので(コンパイルは正常)、なんでだろうと思って調べてみると、巨大な配列はcalloc関数等を用いて作る必要があると知りました。
しかし正直解説サイトを見てもよく意味が分かりませんでした…。

例えばA[1000][1000][1000]の様な配列は、どの様に作ればいいのでしょうか?
A[x][y][z]みたいに表現して、Aを変えて同じ様な配列を8個ほど作りたいです。

初心者なので勉強不足かも知れませんが、どうぞ宜しくお願い致します。

gooドクター

A 回答 (8件)

>計算対象の要素個数は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)バイト目にシークしてアクセスする
方法です。
    • good
    • 1
この回答へのお礼

ご回答有難うございます。
コメントは↑の二回目の方に書かせて頂きます。

お礼日時:2010/11/04 19:05

再び質問がありましたので再登場させて頂きました。


すみません、自分が提示した方法は、サイト等で見かけたって
事ではないので、解説サイトを提示できないのです。

自分は利用した事がないですが、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を組み合わせて、
あとはファイル相手にゴリゴリ処理する……という雰囲気。
全く高度じゃない手法ですが、簡単な事だけが取り柄です(^^;
    • good
    • 0
この回答へのお礼

わざわざご丁寧に有難うございました。

お礼日時:2010/11/06 00:01

巨大なデータをメモリアクセスする手法として、ファイルマッピングという方法があります。


データの実体はファイルですが、プログラムとしてはメモリアクセスで記述ができます。

例えば、4GB長のファイルを、500MBのウインドウを動かしながら、4GBのエリアをアクセスといった事が可能です。実メモリとしては500MBを消費します。

CreateFileMapping で検索すればいろいろ参考になるページがあります。
    • good
    • 0
この回答へのお礼

そんな方法もあるんですね…
勉強してみます、有難うございました。

お礼日時:2010/11/05 08:55

すいません。

訂正します。

>a500というファイルの250*100*sizeof(int)+100*sizeof(int)バイト目にシークしてアクセスする
>方法です。

250*1000*sizeof(int)+100*sizeof(int)
の間違えです。
    • good
    • 0
この回答へのお礼

なるほど…。
なんとなく分かりました…。

軽く調べてみたのですが、http://www.isl.ne.jp/pcsp/beginC/C_Language_16.h … の様な考え方にすればよいのでしょうか?
小さく計算→ファイルに書き出し→必要な時に読み込み→其れを元に計算→上書き。

他の方のアドバイスを含め色々教えて頂けたので、だんだん方向性が見えてきました。
本当にありがとうございます。

お礼日時:2010/11/04 18:57

ずいぶんメモリを使う処理なんですね(^^;


メモリ上で処理しきれない場合は、一度DBなりファイルなりに
吐き出して、それを処理する形にするしかないと思いますよ。

例を拝見する限りでは、扱いたいのは固定長配列という事
なのですよね?ならばいっその事、単純なbyte配列にして、
後はロジック側で対応するのも一案です。固定長ならば、
その処理も簡単ですので。あえて配列にする必要はないと
思いますし、byte配列の方がファイルに吐き出した時に
扱いが楽……かも? もし自分ならばそう作っちゃいます。

ですが、これだと質問に対する答えでなく代替案ですよね。
もし配列にこだわる必要があるならスミマセン。
    • good
    • 0
この回答へのお礼

ご回答有難うございます。

私が余にも知識不足なので、そんな方法が有るとは知りませんでした…。
確かに無理に配列にする必要はありません。

宜しければ、その辺の方法が紹介されているサイトが有れば教えて頂けないでしょうか。

お礼日時:2010/11/04 18:30

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ギガ
それだけのメモリがある事前提での質問でしょうか?
    • good
    • 0
この回答へのお礼

正直、データのサイズの事は分かりませんでした…。
プログラム云々以前に基本的な知識が無かったと思います、勉強不足なのでその辺を勉強してみようと思います。
ご丁寧に有難うございました。

お礼日時:2010/11/04 18:21

そんな巨大な配列で何をやりたいんでしょうか?


目的と手段を履き違えて、「巨大な配列を作る」こと自体が目的化していませんか?
そのあたりを踏まえて、一度再考した方がいいと思いますけど。

OSが書かれてないので参考程度ですが、32bit版Windowsのアプリケーション領域は4GBなので、たとえばAの型が4byte型だとA一つでほぼその全てを使い切ります。
    • good
    • 0
この回答へのお礼

すいません、その辺何も書いていませんでした。
学習の一環(個人的な)で簡単な熱伝導解析をPCにやらせてみたいと思った次第です…。
計算対象の要素個数は3億個ほどです、単純に出来るんじゃないかな?と気軽に考えていましたが、やっぱり大容量な問題もあり難しい事なんですね…。
一度良く考えてみます。
有難うございました。

お礼日時:2010/11/04 18:14

>例えばA[1000][1000][1000]の様な配列は


charの配列だとしても、1000×1000×1000ですから約1GByte、
intの配列であれば約4GByteですから32BitOSでは無理です。

64BitOSだとしても、スワップしまくりで動作がかなり遅くなりそうです。
設計からみなおしたほうがいいでしょう。
    • good
    • 0
この回答へのお礼

有難うございます。

なるほどやはりサイズが大きすぎなのですね… 計算を小さくして何とか試してみたいと思います。
ちなみに配列で表現できる大きさはどの程度が限界なのでしょうか?
また変数として(データ)として保持できるサイズはどれぐらいでしょうか?

宜しくお願いします。

お礼日時:2010/11/04 18:05

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

gooドクター

人気Q&Aランキング