float A[128*128*10*30];
と言うような大きな配列を関数で渡そうとする場合、
関数(Func)での受けとしては
Func(float *FA, , , , ) /* FAがAそのものを表す引数 */
{
}
だと思うのですが、
Mainから出す側としては、
Func(A, , , ,);
の記述でいいのでしょうか?
それとも
Func(*A, , , ,)
でいいのでしょうか?
またこのような大きな配列を持つ変数を多く使うので
リンク中
LNK4084: トータル イメージ サイズ 1804898304 が最大値 (268435456) を越えています
が出て実行できなくなっているので、
メモリの節約に行くのですが、大幅には、使用メモリは減りません。
そう言うところに気をつければバッサリ減らせるのでしょうか?
new や malloc は試してみた?
使い方はこう( malloc の場合):
void Func( float* a, const int size )
{
int i;
for ( i = 0; i < size; i++ ) {
a[ i ] = ( float )i;
}
}
void foo()
{
float* pa = 0;
const int NUMBER_OF_ELEMENTS = 128*128*10*30;
const int ALLOCATE_SIZE = sizeof( float ) * NUMBER_OF_ELEMENTS;
/* 確保 */
pa = ( float* )malloc( ALLOCATE_SIZE );
/* 使用 */
Func( pa, NUMBER_OF_ELEMENTS );
/* 使い終わったら必ず開放する */
free( pa );
}
ありがとうございます。
今のきなみMALLOC、 FREEがらみに
置き換えているところです。
私の2つあるうちの最初の質問は
Mainから出す側としては、
Func(A, , , ,);
の記述でいいのですよね。
↓でOKです。
>Func(A, , , ,);
ただ、このへんの質問があるということは、ポインタを勉強されたほうが
良いと思います。
辛言ありがとうございます。
なんとか、全部大きな配列型の変数をMALLOCとFREEに
変えて、この問題を消せたようです。
時に、
A = (int *) malloc(100 * 256 * 256 * 200 * sizeof(int));
や
B = (float *) malloc(100 * 256 * 256 * 200 * sizeof(float));
と言う変数のエリアを確保出来ているかどうか調べたいのですが、
これは単純に
if (A == NULL)
とか
if (B == NULL)
と聞けばよいのでしょうか?
if (A == NULL)
{
// 確保できなかった場合の処理
}
でOKです。
mallocは
「使えるメモリが足りないときはNULLを返す」とあります。
開発環境にVCがあればHELP→キーワード検索で参照できますよ。
じょじょにMALLOC値がNULLでないかどうかでメモリが確保出来ているかどうかを
確かめて行っていますが、
A = (int *) malloc(100 * 256 * 512 * 200 * sizeof(int));
というようなものを確保しようとする場合、
使った後でFREEしようがしまいが、
占有に1GByteを超えてしまっているので、
メモリ確保は出来ないのですが、
このような時、うまい圧縮なんかはできないものなのでしょうか?
A = (int *) malloc(128 * 256 * 512 * 256 * sizeof(int));
とした場合でも同じでしょうか?
あと、もう一つお願いします。
malloc内の数値が小さいケースはわかるのですが、
S = (float *) malloc(256 * 256 * 256 * 256 * 30 * sizeof(float));
if (S == NULL)
{
printf(メモリ確保出来ず ! \n);
exit(10);
}
ってやったら、なんと、NULLにならず通りぬけて行きました。
120GByteなのに。
信じていいのかな。
(だって、物理的に256MB程度しか積んでないはずなのに。
何か裏技でもシステムがやってるのかな)
それと、やはり確保で時間がかかりすぎ。
30秒~1分くらいかかっていた。
もっと時間をちじめる設定って出来ないのでしょうか?
ちなみに私のところはWINDOWSモードのVC++6です。
何をしたくてこのようなメモリを利用するのか私には理解できないのですが、
根本的にこのようなサイズを使用するようなアプリケーションはあるのですか。
ちなみに
> S = (float *) malloc(256 * 256 * 256 * 256 * 30 * sizeof(float));
mallocの引数は(size_t unsigned int)なので上記のデータは0となります。
> if (S == NULL)
サイズが0のためSはNULLとはなりません
> {
> printf(メモリ確保出来ず ! \n);
> exit(10);
> }
回答ではありません
>ちなみに私のところはWINDOWSモードのVC++6です。
VMウェアを使っているということでしょうか?
Windowsが物理メモリ以上の確保が出来るのはメモリをスワップファイルへ確保するためです
ディスクアクセスを行うため時間が掛るのでしょう
95・98は一度に確保できる最大メモリは理論上2GBだったはずです
NTや2000の場合は理論上2GB以上の確保が出来たはずですが
実際に試したことは無いです
仮想メモリが使われますのでディスクの容量には十分注意してください
最悪起動しなくなることがありますよ
うちは95でのVC++6で使っています。
確認ですが、
メモリが確保されなかった場合は
S = (float *) malloc(256 * 256 * 256 * 256 * 30 * sizeof(float));
の値がNULLで出るということで間違いないですね。
アプリは画像・音声一杯あります。
何故なら、別な変数で
A = (int *) malloc(100 * 256 * 256 * 200 * sizeof(int));
の場合NULLが帰って来て、
A = (int *) malloc(100 * 10 * 256 * 200 * sizeof(int));
にすると帰らなくなりました。
A = (int *) malloc(100 * 256 * 256 * 200 * sizeof(int));
でメモリ確保出来ずと思われるNULLが帰っていたのにのに、
それよりかなりエリアが大きいじゃないかと思われる
CepEachS = (float *) malloc(256 * 256 * 256 * 256 * 30 * sizeof(float));
で帰っていないですね。
(ポインターはintで1バイトずつ、floatで4バイトずつ、doubleで8バイトずつ
進むと言う理解でいいですね。)
いずれにしても仮想メモリが使われるということは、
値としてちゃんと入って来なくなる可能性はありますか?
ともかくアクセスのスピードを何とかして早くしなければ、と思っています。
でもやっぱりおかしいのかなあ。
256 * 256 * 256 * 256 * 30 * sizeof(float)
を計算すると、515Gバイト。
仮想であろうと何であろうと、
これだけのメモリが確保されるのでしょうか?
CepEachS = (float *) malloc(256 * 256 * 256 * 256 * 30 * sizeof(float));
勿論、上記CepEachSと言う変数はNULLでも0でもなっていない訳ですが、
他にメモリが確保されたかどうかの確認の仕方はあるのでしょうか?
>A = (int *) malloc(100 * 256 * 256 * 200 * sizeof(int));
>の場合NULLが帰って来て、
この場合、実際にメモリが確保(5GB→実際は1GB)できなくてNULLに
なったものと思われます。
何度も言いますが、mallocの引数は(size_t unsigned int)のため指定できるのは
4GBまでです。
>A = (int *) malloc(100 * 10 * 256 * 200 * sizeof(int));
>にすると帰らなくなりました。
この場合はメモリ確保が200MBなので一生懸命OSが確保しようとしているのでは・・・
Tjさんのマシンはどの程度メモリをつんでいるんですか。
ちなみに画像・音声の処理も一度に全部のデータをメモリ上にロードしているアプリは
ないんじゃないですか。ほとんどのアプリはハードディスクを利用していると思いますが。
なるほど。
アイススケーターさん。
うちは物理メモリは256MBですね。
でも
A = (int *) malloc(100 * 256 * 256 * 200 * sizeof(int));
が嫌われて、もっとエリアとしては大きいはずの
S = (float *) malloc(256 * 256 * 256 * 256 * 30 * sizeof(float));
が蹴られてないというのも不思議なんですが。
もう一度計算してみてください。
unsigned intは0x00000000~0xffffffffまでです。
>A = (int *) malloc(100 * 256 * 256 * 200 * sizeof(int));
>が嫌われて、もっとエリアとしては大きいはずの
この値は、mallocには5GBではなく1GBとして渡されます。
5GBを0xffffffffでANDしてみると解ります
5GBは0x140000000ですがこれに0xffffffffをANDすると
0x040000000(1GB)となります。
>S = (float *) malloc(256 * 256 * 256 * 256 * 30 * sizeof(float));
この値は、0xf000000000(960GB)ですがこれに0xffffffffをANDすると
0x0000000000(0バイト)となります。
このため、こちらは正常応答となっています。
コンピュータの、データ範囲をしっかり頭に入れておきましょう。