• ベストアンサー

多次元配列のデータ個数やメモリについて

今,2次元配列で, static double g[20000][10] として,配列を使用することを考えています。(他にも一次元配列を多くあります)これを使って計算を行います。 g[20000][9]の場合は正常に動いたんですが,g[20000][10]にするとaccess violation(アクセス違反)のように出ます。メモリの問題でしょうか,それとも限界なんでしょうか,,,,? この解決策はありますか?よろしくお願いします。 Visual C++6.0 で動作

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

  • ベストアンサー
noname#227064
noname#227064
回答No.1

何故数学カテゴリで質問したのかは置いといて、 access violationがでるなら、ソースコードに間違いがあるのではというのが一番考えられることです。 g[20000][9]のときは正常に動いたのではなく、たまたまうまくいっただけで、それがg[20000][10]のときに表面化しただけではないでしょうか。 「double g[20000][10]」のサイズは、 sizeof(double)*20000*10 = 8*20000*10 = 1.52MByte (ただしsizeof(double)=8の場合) なのでメモリの限界ではないでしょう。 ソースコードが出せるのなら、それを見て問題を指摘できるかもしれません。

s034089
質問者

お礼

ありがとうございます。 今日検討した結果うごきました。

その他の回答 (2)

  • R_Earl
  • ベストアンサー率55% (473/849)
回答No.3

ANo.2ですが、2箇所訂正です。 (誤) g[20000][10]で確保されるのは、g[0][0] ~ g[19999][9]までではないでしょうか? (正) 『static double g[20000][10]』というコードで確保されるのは、 g[0][0] ~ g[19999][9]までではないでしょうか? (誤) 2次元配列でも同様に、g[n][m]で確保されるのはg[0][0] ~ g[n-1][m-1]の 合計nm個だけだったと思います。 (正) 2次元配列でも同様に、『static double g[n][m]』というコードで確保されるのは g[0][0] ~ g[n-1][m-1]の合計nm個だけだったと思います。 ちなみにn、mはプログラムにおける変数ではなく、整数(の代わりに使った文字式)です。

  • R_Earl
  • ベストアンサー率55% (473/849)
回答No.2

g[20000][10]で確保されるのは、g[0][0] ~ g[19999][9]までではないでしょうか? int temp[5] という宣言で確保されるのは、 temp[0]、temp[1]、temp[2]、temp[3]、temp[4]の5つです。 2次元配列でも同様に、g[n][m]で確保されるのはg[0][0] ~ g[n-1][m-1]の 合計nm個だけだったと思います。

関連するQ&A

  • 多次元配列の動的メモリ

    1次の配列aの動的メモリは例えば 「double *a;  int num = 3; //配列の数  a = new double [3];」 などとすれば確保できることは分かるのですが、 二次元配列など、多次元配列の動的メモリは どのようにすれば確保できるのですか?

  • 二次元配列を引数として渡し、再び返す方法

    c++を用いてます。 main関数内において、二次元配列(行列)の計算によって各成分の値を求め、 その二次元配列を関数の引数として渡し、成分を用いて計算した後、再び返す方法を知りたいです。 具体的には、ルンゲクッタ法を用いたプログラムで、 #include<iostream> : double g11(double D[][9],double x11~) double g12(double D[][9],double x11~) : int main(void) { (中略)double D[6][9]=などの定義をしています for(i=0;i<100;i+) { 行列の計算(積や逆行列の計算) ルンゲクッタ法 (ここでg11を用います) k111=h*g11(D,x11,…); : dx11=(k111+…)/6.0; : cout<<x11…<<endl; x11+=dx11; x12+=dx12; : } return 0; } double g11 (double D[][9],double x11…) { double dif; dif=D[0][0]*x11+D[0][1]*x12+…   return(dif); } double g12 (double D[][9],double x11…) { double dif; dif=D[1][0]*x11+D[1][1]*x12+…   return(dif); } : というようなプログラムです。エラーは出ないのですが、値が一瞬で発散してします。 ちなみに、D[6][9]は行列の積や逆行列の計算を行った結果得られた二次元配列です。 おそらくポインタをうまく使わないといけないことはなんとなく解るのですが…。 プログラムの説明が解りにくくて申し訳ないのですが、よろしくお願いいたします。

  • 二次元配列について

    二次元配列が確保(?)されてなくて困っています。 プログラム内で、以下のように宣言するのですが、 #define MM 1025 //プログラム6行目 #define NN 10 //7行目 double y[MM][NN]; //17行目 y[0][0] = 3.0; //28行目 Visual Studio.NET のデバッグツールの「ウォッチ」で、 y[0][0]に代入された値を確認しようとすると、 エラー:インデックス'0'は、ポインタ/配列'y'の範囲外にあります と、表示され、中身を確認することができません。 それどころか、プログラムの後半98行目を境に、 y[0][0]の値が上書きされてしまいます。 x[k] = x[0] + k*h; //98行目 ここから、察するにメモリがちゃんと確保されていないと、 思うのですが、どうすればいいかわからず、困っています。 どなたかご教授をお願いいたします。 環境 OS : Windows XP 開発環境 : Visual Studio.NET

  • メモリと配列に関して

    大量のデータを扱うプログラムを作りたいと思っています。 たくさんの配列(配列はDouble型です。)を使うため、 System.outofmemeoryが出てしまいました。 大きい配列を使うための工夫や、現在メモリを2GB積んでる パソコンで計算しているのですが、メモリ容量に換算して どの程度の大きさの配列を作れるのかが教えていただきたいです。 また、これらに関する疑問に答えてくれる書籍やWebサイトでも 教えて頂ければ幸いです。 お手数ですが、よろしくお願いします。

  • pythonの多次元配列へのデータ入力

    pythonの多次元配列で以下のように、ループのカウンタのn,mで配列の位置を指定して代入することができないようです。このような場合どう処理するのでしょうか。 for n in range(1:10) for m in range(1:10) a[n][m]=f(n/m) なお、aについては使用の宣言はしておらず、メモリも確保されていません。fは別途用意されています。 また、a[2][3]=1.3 のように配列の場所を指定して代入するのもダメのようです。numpy.arrayとかで宣言するのかなと思うのですが。使用例が見つかりません。2次元配列だけでなく3次元配列だとどうなるかなと思うのですが。 科学技術計算はこんなのばっかりです。pythonはそのようなものに向くでしょうか。いろんなものがpython対応になってきているので速さの問題があっても器用な処理ができるのなら選択されることも多いと思いますが。 よろしくお願いします。

  • 3次元配列使用でStackOverflowException発生

    C++で3次元配列を使用したいのですが,強制終了させられてしまいます. おそらくスタックオーバーフローというものが起こっているようなのですが, double L[10][500][30],a[10][500][30],b[10][500][30],… というふうに, 10*500*30の要素数の配列を全部で10種類使用するのはやはりメモリ的に無理があるのでしょうか? コード作成はVisual Studio 2008,コンパイラはgccで実行しています. あまりこの要素数は減らしたくないのですが, 何か解決策があれば教えてください. ------------------------------------------------------------ 環境:WinXP, メモリ1GB, Pentium4 ちなみに,いくつか対策を講じて見ましたが,エラーが出てしまった例を一応下に載せておきます. <VisualStudioでデバッグ有りのコンパイル> エラー."System.StackOverflowException' のハンドルされていない例外が発生しました" <new()を使用した配列の動的確保> double ***L, ***a, ・・・; L = new double**[30];// double型30個分の領域を動的確保 a = new double**[30]; … for(k=0; k<=30; k++){ L[k] = new double*[500];// double型500個分の領域を動的確保 a[k] = new double*[500]; ・・・} for(k=0; k<=30; k++){ for(j=0;j<=500; j++){ ☆L[j][k] = new double[10];// double型10個分の領域を動的確保 a[j][k] = new double[10]; ・・・}} ☆:エラー発生."保護されているメモリに読み取りまたは書き込み操作を行おうとしました。他のメモリが壊れていることが考えられます。"

  • 2次元配列のnew

    4x4行列のデータがいくらか書いてあるファイルから、読み込んでvector配列へ保存するプログラムを考えています。 vector配列は、float[4][4]の先頭ポインタの配列です。 宣言はこんな感じで、コンパイルエラーは出ませんでした。 vector<float[4][4]> matrix; つぎに読み込み部分で、下のような感じです。 4x4行列が見つかるたびにこれが実行されます。 GetFloatToken()は、ファイルから要素をひとつ取り出す関数です。 float m[4][4] = new float[4][4]; for(int g=0; g<4; g++) for(int r=0; r<4; r++) m[g][r]=GetFloatToken(); matrix.push_back(m); newの行とpush_backしてる行でエラーが出ました。 自分が思うに、m[4][4]のとこの、newからの受け取りの仕方が悪い気がしました。 そこで、*m[4] や **m とかにして試してみましたがうまくいきませんでした。 どうすればいいんでしょうか。 もしかして、c++では多次元配列のnewは無理なんでしょうか。 わかる方がいましたら、どうか教えてください。 補足: あとで行列の計算をするのが楽なので、float[4][4]の形は変えたくないです。 もし、多次元配列のnewが無理ということなら別の策を考えます。

  • 関数内での多次元配列のメモリの動的確保について

    関数内で、参照渡しをして配列の動的なメモリの確保をしようとしているのですが、うまくいきません。 はじめに、main関数内で、 int main(void){ double *testdata1; testdata1 = (double*)malloc( sizeof(double) * 10 ); if( testdata1 == NULL ){ printf( "ERROR:testdata1" ); exit(0); } testdata1[3] = 20.4; printf( "test = %g\n", testdata1[3] ); } を実行したところうまくいきました。 そこで、 int main(void){ double *testdata1; Kakuho( &testdata1 ); printf( "test = %g\n", testdata1[3] ); } void Kakuho( double **testdata2 ){ *testdata2 = (double*)malloc( sizeof(double) * 10 ); if( *testdata2 == NULL ){ printf( "ERROR:testdata2" ); exit(0); } *testdata2[3] = 20.4; } としましたが、成功してくれません。 コンパイルは通りますが実行するとエラーが発生して落ちます。 (上記のprintfのERRORではありません。) 動作環境はXPのVCC7です。よろしくお願いします。

  • 2次元配列でウォッチが出来ない

    2次元配列でウォッチが出来ない 環境 windowsXP Prp Visual Stadio2003 下記の状況で2次元配列のウォッチが出来ません。 1.Visual Stadio2003を起動 2.ファイル→新規作成→プロジェクト 3.プロジェクトの種類はVisual C++プロジェクトでテンプレートからWindowsフォームアプリケーションを選択して、 プロジェクト名に「test」と入力後OKボタン押下 4.Formの適当な位置にボタンを貼り付ける 5.貼り付けたボタンをダブルクリックしてボタンクリックイベントの中(Form1.h)に以下の処理を記述する char cWork[5][20]; memcpy(&cWork[0],"こんにちは",sizeof(cWork)); 7.memcpy(&cWork[0],"こんにちは",sizeof(cWork)); にブレイクポイントを置いて、デバッグ実行をする 8.フォームのボタンを押下してブレイクポイントで止まったら「cWork」をウォッチする 9.memcpy(&cWork[0],"こんにちは",sizeof(cWork)); をステップ実行後ウォッチで内容を確認すると以下のようになります ━cWork{Length=5}char[][][] ┣━ ┣━ ┣━ ┣━ ┗━ ウォッチは出来ませんが、cWorkの中身をテキストボックスに表示や1次元配列に格納したところ cWorkに正しく値は入っていました。 ウォッチ出来ないのはVisualStadio2003のバグなのでしょうか? お分かりになられる方いらっしゃいましたらご教授お願いいたします。

  • メモリの動的確保(大容量)について

    今640*480の画像を、10枚読み込み、1枚を1行に入れた 2次元配列、10*307200を作りました。これをXとおきます。 この転置行列、307200*10と、Xを掛けて、 307200 * 307200 の行列を作りたいです。 その行列の確保に、 xx = (double (*)[307200])malloc(sizeof(double) * 307200 * 307200); とやったところ、 warning C4307: '*' : 整数定数がオーバーフローしました。 というエラーが出てしまいました。 これって、メモリが確保出来ないっていうエラーですよね? 無知なので教えて頂きたいのですが、 doubleって8バイトなので、この計算だと 8 * 307200 * 307200 = 700G以上のメモリを必要としてしまう。ということでしょうか? そうだとしたら、やっぱり、こんな容量のメモリを確保するのは無謀ですよね。 でも、この計算はしたいのですが、何か方法はありますでしょうか?