• ベストアンサー

メモリ領域の確保の仕方

あまりうまく書けなかったのですがよろしくお願いします。 ファイルから二次配列を読み込むプログラムを作ろうとしました。 /*****行列Aに値を入れる********/ for(i = 0; i < Qap->iN; i++){ for(j = 0; j < Qap->iN; j++){ fscanf(fp, "%d", &Qap->matrixA[i][j]); } } /*****行列Bに値を入れる********/ for(i = 0; i < Qap->iN; i++){ for(j = 0; j < Qap->iN; j++){ fscanf(fp, "%d", &Qap->matrixB[i][j]); } } のように書くために、二次配列の領域を確保しようとしたとき、 #define SIZE 100 //行列のサイズ typedef struct hairetu{ int iN; int matrixA[SIZE][SIZE]; int matrixB[SIZE][SIZE]; }hairetu; としてmatrixA[SIZE][SIZE]のようにした場合は Qap = malloc(sizeof(hairetu));//hairetu分の大きさの領域を確保 とすれば領域を確保できたのですが、 typedef struct hairetu{ int iN; int **matrixA; int **matrixB; }hairetu; のように二次配列を**matrixAと表そうとして、 fscanf(fp, "%d", &Qap->iN); のようにファイルから行列のサイズを読み込もうとした場合、 Qap = malloc(sizeof(hairetu));//hairetu分の大きさの領域を確保 とやってもコンパイルはできるのですがアプリケーションエラーが出てしまいます。 何故だかよくわかりません。 二次配列を**matrixAのように表そうとした場合の領域確保の仕方を教えて下さい。 わかりづらくて本当に申し訳ありませんがお願いします。

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

  • ベストアンサー
noname#5537
noname#5537
回答No.5

こんな方法もあります。 連続したメモリ領域をまとめて確保できるのがちょっと嬉しいです。 タブの代わりに全角スペースを入れているので気をつけてください。 int n = 10; // 動的に確保するので定数でなくてもよい int i, j; int **a; // n*n の(似非)二次元配列を確保 a = (int**)malloc(sizeof(int*)*n); a[0] = (int*)malloc(sizeof(int)*n*n); for (i=1 ; i<n ; i++) {  a[i] = a[i-1] + n; } // 使う for (i=0 ; i<n ; i++) {  for (j=0 ; j<n ; j++) {   a[i][j] = 1;  } } // 解放 free(a[0]); free(a);

taro1177
質問者

お礼

ご回答ありがとうございます。 全く考え付かなかった方法です。 この方法を使ってみたら何とか動かすことができました。本当にどうもありがとうございました。

その他の回答 (4)

  • nagare
  • ベストアンサー率33% (280/831)
回答No.4

二次元配列でしたね Qap = malloc(sizeof(hairetu)); matrixAWork=malloc(sizeof(int)*SIZE*SIZE); matrixBWork=malloc(sizeof(int)*SIZE*SIZE); Qap->matrixA = &matrixAWork; Qap->matrixB = &matrixBWork; に訂正させていただきます

taro1177
質問者

お礼

わざわざありがとうございます。

  • nagare
  • ベストアンサー率33% (280/831)
回答No.3

読み込んだデータはどこへ格納するのでしょうか?? これが答えです 領域の確保と設定は Qap = malloc(sizeof(hairetu)); matrixAWork=malloc(sizeof(int)*SIZE); matrixBWork=malloc(sizeof(int)*SIZE); Qap.matrixA = &matrixAWork; Qap.matrixB = &matrixBWork; となります でも fscanf(fp, "%d", &Qap->matrixA[i][j]); が使えなくなるため typedef struct hairetu{ int iN; int *matrixA; int *matrixB; }hairetuQap = malloc(sizeof(hairetu)); matrixAWork=malloc(sizeof(int)*SIZE); matrixBWork=malloc(sizeof(int)*SIZE); Qap.matrixA = matrixAWork; Qap.matrixB = matrixBWork; がよいでしょう

taro1177
質問者

お礼

丁寧な回答ありがとうございます。 このようにして配列の分も別に領域を確保するのですね。 どうもありがとうございます。

  • hofuhofu
  • ベストアンサー率70% (336/476)
回答No.2

**matrixの領域も別に確保する必要があります。 そのまま使ってしまうと当然メモリ破壊が起きてしまいます。 Qap = (hairetu*)malloc(sizeof(hairetu)); Qap->matrixA = (int**)malloc(sizeof(int*) * SIZE); for(i = 0; i < SIZE; i++) Qap->matrixA[i] = (int*)malloc(sizeof(int) * SIZE); freeも忘れずに。 1つめに合わせてQapはhairetu*型にしましたが、 typedef struct hairetu{ int iN; int **matrixA; int **matrixB; }hairetu; では、**matrixの容量を確保しない限りそれほどメモリを必要としないので、そのままhairetu型にしてみいいと思います。

taro1177
質問者

お礼

Qap->matrixA = (int**)malloc(sizeof(int*) * SIZE); for(i = 0; i < SIZE; i++) Qap->matrixA[i] = (int*)malloc(sizeof(int) * SIZE); **matrixの領域も別に確保する必要があるということですね。 どうもありがとうございます。

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

typedef struct hairetu{ int iN; int **matrixA; int **matrixB; } hairetu; ――だと、構造体は、数値型 + ポインタ型 + ポインタ型の形になりますので、これをmallocしても、実際の二次元配列のメモリは確保されません。 別途mallocして、ポインタに代入する必要があります。

taro1177
質問者

お礼

どうもありがとうございます。大変参考になりました。 頑張ってみます。

関連するQ&A

  • メモリ領域確保に関して

    C言語を始めて3ヶ月の初心者です。 下記のような定義で、領域確保をしたいのですが、 うまい方法がわかりません。 ご存知の方いらっしゃいましたら、 御知恵をお貸し下さいませんでしょうか? <test.h> ================================== #define SIZE_A (5) /* 親構造体 */ typedef struct { int testInt; testSmallStructT *testSmall; // 7バイト構造体の配列 char *testChar; // SIZE_A分の領域*配列数 } testBigStructT; /* 7バイト構造体 */ typedef struct { char str1[3]; char str2[4]; } testSmallStructT; /* メンバ変数 */ testBigStructT gTest[10]; ================================== ここで、あらかじめ全体の領域サイズを算出して、 mallocにてエリア確保を行う方法を求めてます。 また、多数にmallocを使用するとメモリ確保失敗時に、 それまで確保したエリアの開放を行わなくてはいけなくなる懸念から、 できるだけ使用しないようにしたいのです。 メンバ変数gTestを10の配列で持ち、構造体testBigStructTの、 要素testSmallとtestCharを可変の配列として扱いたくポインタ定義をしており、 更に、testCharにSIZE_A(5byte)の領域を確保しようとしております。 最終的には、下記のような使い方をしたいのですが、 メモリ確保の方法がわかりません。 =================================== (EX:) strcpy(gTest[0].testSmall[0].str1,"aaa"); strcpy(gTest[3].testSmall[2].str2,"bbb"); strcpy(gTest[6].testChar[3],"cccc"); =================================== 開放は下記の記述で問題ないと思っております。 free(gTest); 大変申し訳御座いませんが、 ご指摘・ご指導願いませんでしょうか? どうか宜しくお願い致します。

  • 動的なメモリ領域の確保

    double型変数5個分のメモリをmalloc関数により確保し,その確保した要素のアドレスを表示するように,プログラムを作る問題で、 (注)に「 %pで表示するためには,double型へのポインタ(double *)をvoid型へのポインタ(void *)にキャストする必要がある.」と書かれていたのですが、どういうことでしょうか? 以下のようでいいのでしょうか? #include<stdio.h> #include<stdlib.h> #define COUNT 5           // 動的に確保するメモリ領域数を示すマクロ定数の定義 int main(void) {  // 動的に確保するメモリ領域のアドレスを保持するポインタ変数の宣言  double * pointer;  int i;                  // for文で使用する変数の宣言  // int型変数5個分のメモリ領域を確保  pointer = (double *)malloc(sizeof(double) * COUNT);  if(pointer == NULL) {        // メモリ領域の確保が失敗した場合   printf("メモリ領域を確保できませんでした.\n");   exit(1);                // プログラムの終了  }  for(i = 0; i < COUNT; i++)   printf("%d番目のアドレスは%pです.\n", i + 1, pointer + i);  free(pointer);            // 確保したメモリ領域の解放  return 0; }

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

    下記のような構造体が宣言されている場合、 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;

  • 動的メモリの確保の仕方を教えて下さい。

    プログラミングの初心者なのですが、現在256x256x100のバイナリファイルを読み込もうとしているのですが、下のように書くとエラーになってしまいます。動的メモリの確保を行えば、上手くいくと思うのですが。。どなたか教えて頂けないでしょうか?どうぞよろしくお願いします。 const short int SIZE=256; const short int SLICE=100; signed short int matrix[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[i][j][k],sizeof(signed short int)); cout<< matrix[i][j][k]<<endl; } } }

  • newを使った領域の動的確保

    お世話になります。 C++での記述方法なのですが 構造体Testの領域を確保しておいて値を入れます。 確保しておいた領域では領域が不足するときに 不足分を追加したいのですがどうすればよいでしょう? Cではreallocを使えばよいと思うのですが C++ではmallocではなくnewを使ったほうがよいと聞きました。 newした領域を再定義した場合(deleteせずに領域を追加) 先に領域に入れたデータは保証されるのでしょうか? 以下例文ソース*部分 以下例文のソース Test *a; a = new TEST[10]; int cnt; int i; for(i = 0;i<10;i++){  //ここでTESTの配列aに値を入れる } cnt = 12; if( cnt > 10 ){  //予想サイズを上回ったら足りない分のサイズの領域を確保し  //データを入れる  a = new[cnt];//*ここで領域を再確保したら元のa[0]~a[9]の         //データは確実に保持されるのか?         //または他に領域を確保する方法があるのか? } 上記例文ソースでは先にcntで領域を確保すれば良いようにみえますが やりたいことは 先に確保されている領域を広げて 先に入れてあったデータと、広げた領域に入れたデータを使いたい のです。 分かりにくい文章かもしれませんがよろしくお願いします。

  • 領域の確保について

    callocやmallocで領域の確保が出来ると思いますが、領域が確保できなかったりする事があると思います。 char test[100000]; とか配列を宣言した場合も領域が確保されると思いますが、 これは確保する事が出来ない事とかはあるのでしょうか? また確保できなかった場合はどうなるのでしょうか? すいません、なんか勘違いしているかも知れませんが、宜しくお願いします。

  • C++で領域の確保の方法

    今C++の勉強中なのですが、 領域の確保の方法でいい方法が知りたいのです。 ポインターのポインターを使って二次元配列の領域を確保したいのですがいい方法が思いつきません。 int **pBox; pBox = new int *[ 10 ]; for( int i=0; i<10; i++ ) { pBox[ i ] = new int[10]; } //ちなみに今はこんな感じのものしか考え付きませんint型[10][10] を確保したつもりです。 間違っていたら教えていただきたいです。 本題はこちらで、もっと効率のいい確保の方法を知りたいのでご協力を よろしくお願いします。

  • 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)] 分かる方、回答お願いします。

  • mallocによる確保外の領域への参照

    構造体をmallocにより動的確保を行っていたのですが、例えば typedef struct _point{ int x, y; } point; point *pelem_point; pelem_point = (point *)malloc(sizeof(point)*5); このように、point型の構造体を5つ確保するとします。 しかし、 (pelem_point+100)->x = 1; (pelem_point+100)->y = 2; printf("%d\n", (pelem_point+100)->x); printf("%d\n", (pelem_point+100)->y); とやったら、確保していない100個先のところも構造体として利用できました。 なぜなのでしょうか。 自分の考えではこのようになりました。 mallocによりヒープ領域から適当な空いているメモリのアドレスが渡されるため、そこからはヒープ領域より先に、限りがあるまで進めてしまうために確保外のサイズにアクセスしても使えてしまっている。 また、mallocにより確保した場合は使用中のラベルがはられるため他に侵されることはないが、先の例のようにmallocによって確保してない場合はいくら使用できたとしても、空いているとコンピュータでは認識されるため、何かヒープ領域を使う場合に勝手に上書きされてしまう可能性がある。 しかし、この考えでも、なぜ確保外の領域が構造体のサイズ分ずつ区切られているのか納得いきません。 わかる方いましたらよろしくお願いします。

  • アドレス格納のための二次元配列のメモリ動的確保

    アドレス格納のための二次元配列のメモリ動的確保 二次元配列のためにメモリを動的確保しなければならないのですが、 その配列に格納したいものが 「DATA型のポインタ」です。(DATA型はtypedefした構造体です。) プログラム実行中にmallocで確保した、数あるDATA型の構造体の、その先頭アドレスを リストアップするための配列です。 この場合、どのような形でmallocすればよいのでしょうか? 教えていただけるとありがたいです。よろしくお願いいたします。 -- たとえば m×n のint型の配列は、 ◆ int *i; ◆ i = (int *)malloc( m * n * sizeof(int) ); となりますよね。 この要領がでやるのが一般的にわかりやすいものだとするならその方法でやりたい (後発の人が自分のソースコードを読む可能性があるため)のです。 -- 同様にm×nの「DATA型のポインタを格納するための二次元配列」を動的確保したい場合、 ◆ DATA *d; ◆ d = (DATA *)malloc( m * n * sizeof(DATA) ); この文にどのように付け加えたら良いのでしょう? もうあと一歩な気がするのですが(笑)。しかし参考書等で勉強しましたがわかりませんでした・・・。 わかる方、どなたかよろしくお願いいたしますm(_ _)m あとこれだけ通ればコンパイルが通るんです!!!!! たぶん(笑)

専門家に質問してみよう