動的に領域確保した三次元配列でbus errorが発生(Mac OS X 10.5.8 powerPC G5)

このQ&Aのポイント
  • 現在c言語でプログラミングをしているのですが、動的に領域確保した三次元配列に値”0”を入れようとすると、bus errorが発生してしまいます。
  • ソースコード内で、M、J、N、Qというint型の定数を使用していることが分かります。
  • gdbを使用すると、Program received signal EXC_BAD_ACCESS, Could not access memoryというエラーが表示され、BETA[i][j][k]=0.0;の箇所でbus errorが発生していることがわかります。
回答を見る
  • ベストアンサー

動的に領域確保した三次元配列のbus error

現在c言語でプログラミングをしているのですが、動的に領域確保した三次元配列に値”0”を入れようとすると、bus error が発生してしまいます。使用しているのはMac OS X 10.5.8 powerPC G5です。 ソースは以下のようになっています for(i=0;i<M*J;i++){ for(j=0;j<N;j++){ for(k=0;k<Q;k++){ BETA[i][j][k]=0.0; ALPHA[i][j][k]=0.0; } } } このとき、M、J、N、Qはそれぞれint型の定数です。 gdbしてみると結果はこのようになります。 Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_PROTECTION_FAILURE at address: 0x00000000 0x00004208 in sum_product_decode (H=0x1001f0, y=0x100880, transH=0x1002c0, get=0x100760, get_ve=0x100790, snr=6, count=0, matrix=0xbffff140, vector=0xbffff020, synd=0xbffff130) at n_b_LDPC.c:626 626 BETA[i][j][k]=0.0; ご指摘よろしくお願いします。

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

  • ベストアンサー
  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.5

>"double"だとおもいます。 ですよね。 この考え方を拡張すると、 double ***BETA; と定義したBETAが指すのは、double ** 型ですので、 BETA = (double ***) malloc(sizeof(double **) * M * J); であることに気づきますか? つまり、動的確保を行なう際に、 (double ○○) malloc(sizeof(double △△) * 領域確保したい大きさ); と書いたとき、 ○○ に書く * の数が △△ に書く * の数より1個多い、 という関係があることに気づきますか?

yodametabon
質問者

お礼

このやり方で書き直したところ、正常に動きました! 判りやすくステップを踏んで教えていただき、大変わかりやすかったです。 ありがとうございました。

yodametabon
質問者

補足

なんとなく・・・というとおこられてしまいそうですが、 関係はわかりました!

その他の回答 (4)

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.4

>ここが問題になっているのですか? 問題、大ありです。 3次元でなくて1次元の場合を考えてみましょうか。 double *p; というポインターがあって、これが、動的に割り当てたdouble型5個分の領域を指すような コードを考えてみましょうか。 このとき、 p = (double *) malloc(sizeof(○○) * 5); この、○○ には何が入ると思いますか?

yodametabon
質問者

補足

"double"だとおもいます。

  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.3

> address: 0x00000000 アドレスが明後日の方向にいってるみたいですから、うまく割り当てできてないのでは。 3重にmallocしてないとか。

yodametabon
質問者

補足

回答ありがとうございます。 No.1の回答の補足に載せている方法では、 三重にmallocできていないですか?

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.2

sizeof() のカッコの中が、すべて double * になっているのは、どうしてですか?

yodametabon
質問者

補足

領域確保部分については、先人のものをコピペして 使わせていただいているので、自分でもよくわからずに 使用してしまっています。 ここが問題になっているのですか?

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.1

>動的に領域確保した三次元配列 >ソースは以下のようになっています そこだけじゃなくって、全体を見せてほしいなぁ、なんて思ったりしています。

yodametabon
質問者

補足

回答ありがとうございます。全体だとあまりにも多く なってしまうので、関係ありそうなところをかいつまんで 載せさせていただきます。 double ***BETA,***ALPHA; BETA= (double ***)malloc(sizeof(double *) * M*J); for(i=0;i<M*J;i++){ BETA[i] = (double **)malloc(sizeof(double *) * N); for(j=0;j<N;j++){ BETA[i][j] = (double *)malloc(sizeof(double *) * Q); } } ALPHA= (double ***)malloc(sizeof(double *) * M*J); for(i=0;i<M*J;i++){ ALPHA[i] = (double **)malloc(sizeof(double *) * N); for(j=0;j<N;j++){ ALPHA[i][j] = (double *)malloc(sizeof(double *) * Q); } } for(i=0;i<M*J;i++){ for(j=0;j<N;j++){ for(k=0;k<Q;k++){ BETA[i][j][k]=0.0; ALPHA[i][j][k]=0.0; } } }

関連するQ&A

  • 配列のエラーに関して

    java言語を用いて,Householder変換を用いた固有値の数値計算に挑戦してみました.しかし,次のようなエラーが発生し上手くいきません.どなたかこの問題を解決するためにお力をかしていただけないでしょうか. ----------エラー内容-------------------------------------------------------------------------------- Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0 at Out.Mhouse(House.java:90) at House.main(House.java:10) ---------------------------------------------------------------------------------------------------- //Householder変換 public class House{ public static void main(String[] args){ double[][] A = new double[3][3]; int n = A.length; Out out = new Out(); for(int i = 0;i < n;i++){ for(int j = 0;j < n;j++){ if(j < n-1){ System.out.print(out.Mhouse(A)[i][j] + " "); }else if (j == n-1) System.out.println(out.Mhouse(A)[i][j]); }; }; }; }; class Out{ double[][] outpro(double[] x){ int n; n = x.length; double[][] A = new double[n][n]; for(int i = 0;i < n;i++ ){ for(int j = 0;j < n;j++){ A[i][j] = x[i] * x[j]; } } return A; }; double[][] Msca(double a,double[][] A){ int n = A.length; for(int i = 0;i < n; i++){ for(int j = 0;j < n;j++){ A[i][j] = a * A[i][j]; } } return A; }; double selfpro(double[] x){ double a = 0; int n = x.length; for(int i = 0;i < n; i++){ a = a + x[i] * x[i]; }; return a; }; double[] minus(double[] x, double[] y){ int n = x.length; double[] z = new double[n]; for(int i = 0;i < n;i++){ z[i] = x[i] - y[i]; }; return z; }; double[][] house_1(double[] x){ int n = x.length; double[][] A = new double[n][n]; for(int i=0;i < n;i++){ for(int j = 0;j < n;j++){ if(i == j){ A[i][j] = 1 - Msca(2/selfpro(x),outpro(x))[i][j]; }else{ A[i][j] = - Msca(2/selfpro(x),outpro(x))[i][j]; }; }; }; return A; }; double[][] house_2(double[] x){ double[][] z = new double[1][1]; z[1][1] = 1 - 2; return z; }; double[][] Mhouse(double[][] A){ int n = A.length; double[][] H = new double[n][n]; for(int i = 0;i < n;i++){ double[] x = new double[n-i]; double[] y = new double[n-i]; double[][][] L = new double[i][n-i][n-i]; for(int j = 0;j < n-i;j++){ x[j] = A[i][i+j]; if(j == 0){ y[j] = 1; }else{ y[j] = 0; }; x[j] = y[j] - x[j]; }; if(i < n-1){ L[i] = house_1(x); for(int k = 0;k < n-i;k++){ for(int l = 0;l < n-i;l++){ H[i+k][i+l] = L[i][k][l]; }; }; }else if(i == n-1){ L[i] = house_2(x); for(int k = 0;k < n-i;k++){ for(int l = 0;l < n-i;l++){ H[i+k][i+l] = L[i][k][l]; }; }; }; }; double[][] B = new double[n][n]; for(int i = 0;i < n;i++){ for(int j = 0;j < n;j++){ for(int k = 0;k < n;k++){ B[i][j] = H[i][k] * A[k][j]; }; }; }; return A; }; };

    • ベストアンサー
    • Java
  • 2次元配列にポインタを格納

    http://www.okweb.ne.jp/kotaeru.php3?q=505241の訂正版の質問です。 VC++6.0を使っております。 下のようなプログラムを作ってみました。 #include <stdio.h> #include <vector> using namespace std; class c{ public: c(); virtual ~c(); int get(){return j;}; void set(int i){j=i;}; private: c(const c &right); const c &operator=(const c &right); int j; }; void main(){ vector <vector<c*> > a; c *b; for(int n=0;n<10;n++){ for(int i=0;i<10;i++){ b=new c; a[n].push_back(b); } } for(int j=0;j<10;j++){ for(int i=0;i<9;i++){ a[i][j] -> set(i+j); } } for(j=0;j<10;j++){ for(int i=0;i<9;i++){ printf("%d ",a[i][j] -> get()); } printf("%d\n",a[9][j] -> get()); } for(int i=0;i<10;i++){ for(int j=0;j<10;j++){ delete a[i][j]; } } } すると、コンパイルには成功するのですが、実行は出来ません。 その理由は、「外部参照1が未解決」だそうです。 アドバイスをお願いいたします。

  • 二次元配列とポインタについてよくわかりません2

    先ほどもしつもんして自分なりに改良をくわえたのですが 上手くいきません。 int main( void ) {  int i, j;  /*4 x 4 行列 A*/  double a[4][4];  double *pa;  /*4 x 4 行列 B*/  double b[4];  double (*pb)[4];  /*4 x 4 行列 C*/  double c[4];  double (*pc)[4];  pa = a;  pb = b;  pc = c;  printf("4 x 4 行列 Aの要素を入力してください>\n");  for(i = 0; i < 4; i++){   for(j = 0; j < 4; j++){    printf("A[%d,%d]=", i + 1, j + 1 );    scanf("%lf", (*(pa + i) + j)); }} printf("4 x 4 行列 Bの要素を入力してください>\n"); for(i = 0; i < 4; i++){  for(j = 0; j < 4; j++){   printf("B[%d,%d]=", i + 1, j + 1 );   scanf("%lf", &pb[i][j]); }} としたところ(途中までを表記してます)  pa = a;  pb = b;  pc = c; のところでコンパイル時に 警告で問題のあるポインタの変換とでます なぜおかしいのかまったくわからないので よければ教えてください

  • 三次元配列の動的メモリの確保?

    const int SLICE=2; const int SIZE=256; signed short int *matrix=new signed short int[SLICE][SIZE][SIZE]; for(int i=0; i<SLICE; i++){ for(int j=0; j<SIZE; j++){ for(int k=0; k<SIZE; k++){ fin.read((char*) &matrix[SLICE][SIZE][SIZE],sizeof(signed short int)); } } } delete[] data; 三次元データを読み込むために、三次元配列を使って読み込もうとしたのですが、上手く読み込めません。 三行目の所で、error C2440: '初期化中' : 'short (*)[256][256]' から 'short *' に変換できません。 七行目の所で、error C2109: 配列または、ポインタでない変数に添字が使われました。 というエラーがでます。動的メモリの確保の仕方がまずいのでしょうか? どなたか教えて頂けますでしょうか?よろしくお願いします。

  • 二次元配列について

    下記のプログラムにてNが100の時はコンパイル/実行 ともに出来ます。しかし、Nを1024にするとコンパイル は出来るのですが、実行すると"セグメンテーション 違反です"と言われてしまいます。 Cの文法的には正しいと思うのですが、何がいけない のでしょうか? 動作環境はPen4+Linux 2.4.20です。 よろしくお願いします。 ------ ↓以下プログラム #include <stdio.h> #define N 100 //1024 main(){ int i,j; double aa[N][N]; for(i=0;i<N;i++) for(j=0;j<N;j++) aa[i][j]=0; }

  • 多次元配列の初期化

    多次元配列の初期化を行いたいのですが、 下記の方法では、配列の値が多くなったときに大変 なので他に良い方法はありませんでしょうか? char lesson[7][6] = { {'A', 'B', 'C', 'D', 'E', 'F'}, {'G', 'H', 'I', 'J', 'K', 'L'}, {'M', 'N', 'O', 'P', 'Q', 'R'}, {'S', 'T', 'U', 'V', 'W', 'X'}, {'Y', 'Z', 'a', 'b', 'c', 'd'}, {'e', 'f', 'g', 'h', 'i', 'j'}, {'k', 'l', 'm', 'n', 'o', 'p'}, };

  • 配列について

    以下の配列についての問題でわからないことがあるので、教えてください。 /* x と y の積を求める。 */ #include <stdio.h> int main(void) { int x[2][3] = {{1,2,3}, {4, 5, 6}}; int y[3][2] = {{1, 5}, {5, 3}, {8, 1}}; int ans[2][2] = {0}; int i, j, k, temp; for(i = 0; i < 2; i++) { for (k = 0; k < 2; k++) { temp = 0; for(j = 0; j < 3; j++) { temp += x[i][j] * y[j][k]; } ans[i][k] = temp; } } for(i = 0; i < 2; i++) { for(j = 0; j < 2; j++) { printf("%4d",ans[i][j]); } putchar('\n'); } return(0); } 以下の部分について詳しく説明してもらえないでしょうか? int ans[2][2] = {0};  int i, j, k, temp; for(i = 0; i < 2; i++) { for (k = 0; k < 2; k++) { temp = 0; for(j = 0; j < 3; j++) { temp += x[i][j] * y[j][k]; } ans[i][k] = temp; } }

  • 二次元配列とポインタについてよくわかりません

    二次元配列の要素を代入しようと思って double *pa; for(i = 0; i < 4; i++){ for(j = 0; j < 4; j++){ printf("A[%d,%d]=", i + 1, j + 1 ); scanf("%lf", pa + i + j); printf("A[%d,%d]=%g\n", i + 1, j + 1, *(*(pa + i) + j) );}} とやっているのですがどうやらscanfで上手くいかず最後のprintfが表示されません あと double (*pb)[4]; printf("4 x 4 行列 Bの要素を入力してください>\n"); for(i = 0; i < 4; i++){ for(j = 0; j < 4; j++){ printf("B[%d,%d]=", i + 1, j + 1 ); scanf("%lf", &pb[i][j]);}} もうまくいきません (二通りの方法でしなければ成らないので) どうしたらいいでしょうか?

  • 2次元配列の基礎について

    とある問題で 下に示す行列x,yの積を求めるプログラムを作成せよ。 x=[123][456] y=[15] [53][81] 問題の意味が自分にはよくわからないのですが この場合 123*15;123*53;123*81 456*15;456*53;456*81 の解答を表示させればいいのでしょうか? 自分でやったら以下のようになりましたが、これだと456*53と123*15と0しか表示されません。どこをどう直せば宜しいでしょうか? ご教授お願いしますm(__)m #include <stdio.h> int main(void){ int ma[3][1] ={{123},{456}}; int mb[3][1] ={{15},{53},{81}}; int mc[3][1] ={0}; int i; int j; for(i=0;i <= 3;i++){ for(j=0;j <= 1;j++){ mc[i][j] =ma[i][j] * mb[i][j]; } } for(i=0;i <= 3;i++){ for(j=0;j <= 1;j++){ printf("%3d",mc[i][j]); putchar('\n'); } } return 0; }

  • C++ の多次元配列なんですが

    int i,j; int (*p)[2][3]; int *x; int a[2][3] = {{1,2,3},{4,5,6}}; p = &a; x = &a[0][0]; for ( i = 0; i < 2; i++ ) { for ( j = 0; j < 3; j++) { printf (" %d", (*p)[i][j]); } } printf (" | "); for ( i = 0; i < 2; i++ ) { for ( j = 0; j < 3; j++) { printf (" %d", *(x + ( i * 3 + j )) ); } } printf (" | "); for ( i = 0; i < 6; i++ ) { printf (" %d", *(x + i) ); } これで大丈夫でしょか?

専門家に質問してみよう