• ベストアンサー

配列の確保の仕方

C言語でプログラムを記述していますが、 確保している配列が多すぎるためか、 access vilation at ・・・ などのエラーが出ます。 <プログラム> #define A 1000 #define B 10000 をグローバルで宣言して、各関数内でこれを用いて宣言しています。 int data[A][B]; double root[A][B];   ・   ・   ・ int score[A][A][B]; などを初めにたくさん宣言しています。 聞くところによると、動的に確保すればいい、とも聞いたんですが、あまり意味がわかりません。 上のエラーメッセージが出ないようにするにはどうすればいいのでしょうか? この説明だけでお分かりいただけないなら、言っていただければ詳しく言います。

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

  • ベストアンサー
  • bugmaru
  • ベストアンサー率38% (76/195)
回答No.3

malloc()で必要な時に必要なだけメモリーを確保し、不要になったメモリーはfree()で解放して下さい。 動的にメモリを取得するプログラムは、取得したメモリの管理と解放をきちんとプログラミングしないと、メモリーリークという凶悪なバグプログラムの元になるので慎重にプログラミングしてください。

handle100
質問者

お礼

ありがとうございました。

その他の回答 (7)

回答No.8

handle100さん、こんにちは。 大分経ちますが、もう解決したのでしょうか。 >C言語でプログラムを記述していますが、 >確保している配列が多すぎるためか、 配列が多すぎるためにエラーが出ていると判断した根拠は何ですか。「access vilation at ・・・」と言うエラーならば不正なメモリーにアクセスしたということであり、配列確保との関連性は薄いでしょう。よくあるパターンはポインターの初期化忘れ、同じファイルを2回 freeしようとした事などかな。 >access vilation at ・・・ >などのエラーが出ます。 などというからには、他にもエラーが出ているのですか。であれば、そのエラーのメッセージも書いて下さい。

  • uyama33
  • ベストアンサー率30% (137/450)
回答No.7

プログラミングの分野は 何ですか?  それがはっきりすれば、 行列計算の専門的な本もありますので、 文献を紹介してくださる方も現れると思います。 64ビットのコンピュータが必要かもしれませんね。

  • arukamun
  • ベストアンサー率35% (842/2394)
回答No.6

こんにちは >access violation at >確かにそうです。 > >>ところで、そんなに大きな配列を沢山宣言しなく>てはいけないプログラムなのでしょうか? >プログラムはかなり大きいですね。 >まだ足りないくらい・・・ 仮に、コンパイル出来たとしても、これだけのものをメモリーに展開出来るとは思えませんので、結果的にファイルにキャッシュされてしまいますよね。 それなら、はじめから各データをファイルでやりとりすれば良いと思います。 ファイルにしても、ばかでかい容量が必要になりますね。 根本から考え直した方が良さそうですね。

noname#30727
noname#30727
回答No.5

>int score[A][A][B]; この配列が問題です。これだけで40GBに近い大きさです。32bitのOSであれば、単純に動的確保という事では済まないでしょう。 巨大な配列に頼らないアルゴリズムを使用するか、巨大なファイルを作成して、ファイルの読み書きをするしかありません。

handle100
質問者

補足

訂正・・int score[A][B]。 すいません。

  • uyama33
  • ベストアンサー率30% (137/450)
回答No.4

配列データに、ランダムなアクセスをしますか? そうでないなら、ファイルに保存してしまったらいかがでしょうか? ファイルには、連続的な名前をつけて 必要なときに、必要なものだけオープンする。 話によれば、ファイルサイズは 4Gまで取れそうです。 いかがでしょうか? できれば、他の人の言われるとおり 動的に確保するべきです。 考え方のポイントは 配列が、同時にメモリー上に存在しなくてはならない のか否かです。

handle100
質問者

補足

ファイルの保存というのは、 fopenでファイルを"w(ライト)"モードで開いて書き込むというのですか?

  • net-in
  • ベストアンサー率12% (1/8)
回答No.2

malloc関数を使ってみてはいかがでしょうか。 <stdlib.h>にありますよ。 詳しい使い方は参考URLをどうぞ~

参考URL:
http://www9.plala.or.jp/sgwr-t/lib/malloc.html
handle100
質問者

お礼

ありがとうございました。

  • arukamun
  • ベストアンサー率35% (842/2394)
回答No.1

こんにちは >access vilation at ・・・ スペルはあってますか? access violation at ・・・ かな? ところで、そんなに大きな配列を沢山宣言しなくてはいけないプログラムなのでしょうか?

handle100
質問者

補足

>access violation at 確かにそうです。 >ところで、そんなに大きな配列を沢山宣言しなくてはいけないプログラムなのでしょうか? プログラムはかなり大きいですね。 まだ足りないくらい・・・

関連するQ&A

  • ポインタ配列の動的確保

    ポインタの配列の動的確保について教えてください。 入力した数値をポインタ配列に入れるプログラムです。 下記のように書いてみました。(見づらくてごめんなさい) #include<stdio.h> #include<stdlib.h> #define kensu 3 main() { char abc[kensu+1]={'A','B','C','\0'}; char *ptr[kensu]; int i; printf("3つの整数を入力して下さい。\n"); for(i=0;i<kensu;i++){ ptr[i]=(char*)malloc(sizeof(char)*10); if(ptr[i]==NULL){ printf("メモリの取得に失敗しました"); exit(1); } printf("整数%c:",abc[i]); fgets(ptr[i],10,stdin); if(ptr[i][strlen(ptr[i])-1]=='\n') ptr[i][strlen(ptr[i])-1]='\0'; } for(i=0;i<kensu;i++) free(ptr[i]); } ちゃんと動いているようです。 しかし、ポインタ配列の動的確保をネットで調べてみると、ポインタのポインタ(?)を使って、下記のように2度mallocしています。 #include <stdio.h> #include <stdlib.h> #define N 3 int main(void) { char** arr; int i,j; arr = (char**)malloc(N * sizeof(char*)); /* ポインタ配列を確保 */ /* 配列の要素それぞれにつき、メモリ領域を確保 */ for(i=0;i<N;i++) arr[i] = (char*)malloc(N * sizeof(char));   ・・・ ポインタの配列を宣言して、配列の各要素に動的確保するのと ポインタのポインタを宣言し、ポインタ配列を動的確保して、再度配列の要素に動的確保するのとでは、何か違いがあるのでしょうか? ポインタのポインタを宣言し、ポインタ配列を確保する必要性が良く分かっていないのです。 ネット等で調べて見たのですが、理解力がないのかよく分かりませんでした。 どうか教えてください。

  • C言語 配列の確保

    はじめまして。C言語の勉強を最近始めたのですが、 以下のプログラムで教えていただきたい点があります。 #include <stdio.h> #include <math.h> #define x 10000 #define y 200000 #define z 1.0E-12 #define k 1.38 #define kE 1.0E-23 #define h 6.63 #define hE 1.0E-34 #define c 3.00 #define cE 1.0E+08 void main(void){ int i; double A[x+1]; double B[x+1]; for(i=0;i<=x;i++) { A[i]=(i+y)*z; B[i] = exp(-(h*hE*c*cE)/(A[i]*k*kE*1000)); printf("%e %e\n",A[i],B[i]); }} このプログラムで、xを100000にするとプログラムが動かなくなってしまいます。OSはWindowsXP、ソフトはVisual C++ 6.0を使っています。 解決方法を教えていただけないでしょうか。

  • 配列について。

    配列について質問なんですが int a[6]={1,2,3,4,5,6}; int b[3]={6,32,4}; という配列を宣言し、この二つの配列を足す方法はどのようなやりかたがあるのでしょうか? つまり cc[]という新たな配列を作り cc[9]={1,2,3,4,5,6,6,32,4}; とするにはどのように記述すればいいのでしょうか? 教えて頂ければ幸いです。

  • VC++6.0での配列の動作不良

    現在、VC++6.0のWin32 Console Applicationプロジェクトでプログラムを書いているのですが、配列の様子がおかしいです。 具体的に言うと、ヘッダで #define N 10 #define NN (2*N*2*N) double A[NN+1][NN+1],S[NN+1][NN+1]; double B[NN+1],C[NN+1]; と配列を宣言しているのですが、A,B,Cそれぞれの配列への値の書き込みは普通に行えるのですが、 Sに値を書き込んでいる最中にプログラムが強制終了していまします。エラーメッセージなどはでません。 デバッグすると、Sに値を書き込むfor文の繰り返しの最後のほうに バンドルされていない例外は***.exeにあります。0xC0000005:Access Violation というメッセージが出てそこでプログラムが終了してしまいます。なぜでしょうか? AとSのfor文はまったく同じで、SかわりにAを使うと、このエラーは生じません。 またヘッダで、 #define N 10 #define NN 400 double A[NN+1][NN+1],S[NN+1][NN+1]; double B[NN+1],C[NN+1]; とNNを数字で表すとこのエラーが生じず、普通に実行されます。なぜこのようなことが起こるのでしょうか? どなたか教えていただければ幸いです。お願いします。

  • 配列が0から確保される理由

    配列を確保すると int a[3]; とするとa[0]から確保されます。 なぜだが忘れてしまいました。 誰か教えてください。 すいません。

  • エクセルVBA 必要な数だけ配列を確保する方法は?

    Dim a(10,1)と宣言して、セルにある10個のデータを配列aに代入したいのですが、セルに何個のデータがあるかはプログラムを書いているときには分かりません。 セルにあるデータは、プログラムを走らせるとn個あることが分かります。 それからDim a(n,1)と宣言できれば、必要な数の配列が確保できるのですが、このように必要な数だけ配列を確保するにはどうすれば良いのでしょうか?

  • 2次元配列の動的確保&配列の添え字の書式について

    (1)2次元配列の動的確保について 1次元配列の動的確保は理解できたのですが、次のプログラムの 文(ⅰ)~(ⅱ)の意味を理解できていないので教えてください。 int **a, j, k, nrows=3, ncolumns=4 ; a = (int **)malloc(nrows * sizeof(int *)); a[0] = (int *)malloc(nrows * ncolumns * sizeof(int)); …(ⅰ) //先頭アドレスに… for(j = 1; j < nrows; j++) a[j] = a[0] + j * ncolumns; …(ⅱ)   //この行が特にわかりません。 (2)配列の添え字について この書き方はどういう意味になりますか? out[X_SIZE * (i) + (j)] 分かる方、回答お願いします。

  • 基本的な領域確保の仕方について

    下記のような構造体が宣言されている場合、 A.c.e ←を配列扱いにし、 A.c.e[0].g.h ←を配列扱いにし、 A.c.e[0].g.h[0].iにデータを設定するには、 どのように領域を確保すれば良いのでしょうか? eee型はポインタ宣言のみされていて配列宣言されて いません。(Max10配列) typedef struct { int len; char *i; } hhh; typedef struct { int number; hhh *h; } ggg; typedef struct { fff f; ggg g; } eee; typedef struct { int number; eee *e; } ccc; typedef union { aaa a; bbb b; ccc c; ddd d; } A;

  • 動的メモリ確保の外部関数

    画像処理関係のプログラムを作成しているのですが(C言語で)、動的にメモリ確保をすることが頻繁にあります。 そこで、どんな型(int,char,double,etc..)の場合でもメモリ確保できるような、1つの外部関数を作成したいと考えています。 例えば、 int Memory(引数) { 型宣言; int型の動的メモリ確保; char型の動的メモリ確保; double型の動的メモリ確保; return 0; } イメージでは、上のような感じです。 もしかして、このような考えは、不可能でしょうか? どなたか良いアドバイスがあれば、ご教授ください。 よろしくお願いします。

  • 配列の疑問。

    もうすぐC言語のテストがあるので適当に自分で問題を作って プログラムを作る練習をしていたのですが配列の所でちょっと疑問に思いました。 問題 ひとつずつ数字を入力していき、それまでの数字の合計と平均を求めるプログラム。 0を入力するとプログラム終了(配列、ポインタ、関数を用いること) #include <stdio.h>    int wa(int *a,int b); main() {    int a[10],ans,i=0,c;    double ave=0,j;    while(1)    {      scanf("%d",&a[i]);      c=a[i];      i++;      if(c==0){         exit(1);      }      ans=wa(&a[0],i);      printf("合計%d\n",ans);      j=i;      ans=wa(&a[0],i);      ave=ans/j;      printf("平均%lf\n",ave);      printf("計算回数%d回\n",i);    } } int wa(int *a,int b) {    int ans=0,i;    for(i=0;i<b;i++){      ans+=*(a+i);    }    return ans; } このようなプログラムで一応自分の期待通りには動いてくれたのですが、 こういう「0」を入力しない限り終わらないプログラムのときに配列を利用すると どれぐらい領域を取っておくかがわからないんですよ。 今回はa[10]としてますが、結局10しか確保してないから10回しか入力できないかな? っと思って実行してみますが普通に10回以上でもエラーがでることもなく実行できるんですよね。 これはなぜでしょうか? 私の配列の考え方がまちがっているのでしょうか?