• 締切済み

動的に確保した配列のファイルへの書き出し

動的に確保した配列を、ファイルに書きだそうとしています。 int i, arraysize = 10; int **array; array = new int*[ arraysize ]; for (i = 0 ; i < arraysize ; i++) array[ i ] = new int [ arraysize ]; ofstream out("filename", ios::out | ios::binary); out.write((char *) array, sizeof( array )); これでは array のポインタが書き込まれるだけ、なのかな ? ということで、配列を書き込む目的を果たせておりません。このように動的に確保した多次元配列 (要素数は既知) をファイルに書き込むためにはどうすればよろしいでしょうか。

みんなの回答

  • anzu-k
  • ベストアンサー率66% (2/3)
回答No.5

油断してました。ANo.4の最終行 array[0][arraysize] は array[0][arraysize-1] です。 質問のような配列の場合はarray[0][arraysize-1]とarray[1][0]は不連続です。

  • anzu-k
  • ベストアンサー率66% (2/3)
回答No.4

ANo.1、ANo.2の修正ですが、 質問内容の >out.write((char *) array, sizeof( array )); の行を for ( int i = 0; i < arraysize; i++ ) { out.write( (char*)array[i], arraysize*sizeof(**array) ); } としてはどうでしょうか。 TacosanさんのANo.2は結果的に大丈夫そうですが、 array[i]はint*型なので、 たまたまポインタ(アドレス)型とint型のサイズ(バイト数)が、 一致しているだけなような気がします。 例えば out.write( array[i], arraysize*sizeof(int) ); out.write( array[i], arraysize*sizeof(**array) ); out.write( array[i], arraysize*sizeof(*array[i]) ); ちなみに配列の不連続についてですが、 arraysize長の配列をarraysize個だけ動的に割り当てているだけなので、 array[0]配列とarray[1]配列との間の連続性は保障されません。 array[0][0]とarray[0][1]・・・array[0][arraysize]は連続したものとして扱えます。

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

>また、配列に動的確保した領域は必ずしも連続した領域ではありません >int nn = array[1] - array[0]; >とした場合 nnがarraysizeにはならない場合があるでしょう 本当でしょうか。 仮に、動的に確保した領域(配列とは別物)が連続していない(飛び飛び)とします。 このとき、例えば、当該領域を指すポインターをインクリメントしていくうちに、 確保していない領域を指すおそれがありますね。飛び飛びだから。 そういう状況を引き起こすのは、いささかまずいのではないでしょうか。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

out.write( array[i], arraysize ); じゃなくて out.write(array[i], arraysize*sizeof array[i]); かな>#1. 多分 sizeof array[i] を掛けないとまずいと思う.

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

out.write((char *) array, sizeof( array )); この状態では 書き込むのは 4バイトだろうと思います # char*のサイズは環境依存だったように思います また、配列に動的確保した領域は必ずしも連続した領域ではありません int nn = array[1] - array[0]; とした場合 nnがarraysizeにはならない場合があるでしょう out.write((char *) array, sizeof( array )); の状態では array[0]の内容 つまり for (i = 0 ; i < arraysize ; i++) array[ i ] = new int [ arraysize ]; で確保したアドレスが書き出されるだけだと思います array[i][j]の中身を出力するなら for ( int i = 0; i < arraysize; i++ ) {   out.write( array[i], arraysize ); } といった具合でしょう または 確保を char* array; array = new char[ arraysize * arraysize ]; と確保して out.write( array, arraysize * arraysize ); なら一度で書き込めるでしょう

関連するQ&A

  • 画像を読み込む配列の確保。

    C言語について質問です。 画像を読み込む時、その画像の幅、高さを入力し、そのサイズに見合った配列を確保します。その後ファイル名を入力し、配列に読み込むプログラムを作成しました。 メインの部分のみ記述します。 int xsize, ysize, i; unsigned char **src; char filename[30]; FILE *fp; printf("ファイル名を入力してください:"); scanf("%s", filename); printf("画像の幅:");scanf("%d", &xsize); printf("画像の高さ:");scanf("%d", &ysize); src = (unsigned char **)malloc(sizeof(unsigned char *) * ysize); for(i=0; i<ysize; i++) src[i] = (unsigned char *)malloc(sizeof(unsigned char) * xsize); fp = fopen(filename, "rb"); fread(src[0], sizeof(unsigned char), xsize * ysize, fp); このように記述し、エラーもなく実行できたのですが、srcをこのまま出力すると変?な画像となって出力されてしまいました。 上のように記述した場合、矛盾する場所はあるでしょうか? そして、この方法以外に配列を確保する方法はあるでしょうか?

  • 2次元配列の動的確保

    ある画像を読み込むため、その画像を格納できる幅、高さを持った配列を動的に確保しようと考えています。 幅をxsize、高さをysizeで次のように記述しました。 unsigned char **src; int i; src = (unsigned char**)malloc(sizeof(unsigned char*) * ysize); src[0] = (unsigned char*)malloc(sizeof(unsigned char) * xsize * ysize); for(i=1; i<ysize; i++) src[i] = (src[0] + i * xsize); わざわざポインタのポインタを使用したのは、動的に確保した配列を2次元的なアクセスをしたかったためです。 画像の読み込み時は fread(src[0], sizeof(unsigned char), xsize * ysize, fp); としています。 上に記述したソースは問題なく動作しました。 しかし、上の場合だと全ての配列を連続して確保することができません。つまりsrcでmallocを一回、src[0]でmallocを一回使っているため、ポインタの配列の直後に配列を確保する保障がありません。そこでいっぺんに確保することを考えました。 unsigned char **src; int i; src = (unsigned char **)malloc(sizeof(unsigned char *) * ysize + sizeof(unsigned char) * xsize * ysize); for(i=0; i<ysize; i++) src[i] = (unsigned char *)(src + sizeof(unsigned char *) * ysize + i * xsize); このように組み上げ、読み込み時は上のfreadと同様に記述したところエラーが出てしまいました。 やはり一行目のmallocで無理やりsizeof(unsigned char *) * ysize + sizeof(unsigned char) * xsize * ysize分確保するのは失敗だったのでしょうか?

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

    ポインタの配列の動的確保について教えてください。 入力した数値をポインタ配列に入れるプログラムです。 下記のように書いてみました。(見づらくてごめんなさい) #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));   ・・・ ポインタの配列を宣言して、配列の各要素に動的確保するのと ポインタのポインタを宣言し、ポインタ配列を動的確保して、再度配列の要素に動的確保するのとでは、何か違いがあるのでしょうか? ポインタのポインタを宣言し、ポインタ配列を確保する必要性が良く分かっていないのです。 ネット等で調べて見たのですが、理解力がないのかよく分かりませんでした。 どうか教えてください。

  • 「動的確保した2次元配列のメモリ解放」を関数化したい

    質問タイトルの通りですが、 「動的確保した2次元配列のメモリ解放」をC言語で関数化したいと思っています。しかし、関数の引数には動的確保した配列の先頭アドレスのみ渡す形にしたいです。そのような場合の関数化は可能ですか? どうもうまくいかず、困っています。 以下、具体的に、サンプルソースを記述します。 わかる方、よろしくお願いします。 //====================================================// #include<stdio.h> unsigned char** AllocByteArray2d(int column, int row); void FreeByteArray2d(unsigned char** box); int main(voidls){ unsigned char array**; array = AllocByteArray2d(2, 3); FreeByteArray2d(array); return 0; } unsigned char** AllocByteArray2d(int column, int row){ unsigned char* box; box = (unsigned char**)malloc( sizeof(unsigned char*)*column ) int i; for(i=0; i<column; i++){ box[i] = (unsigned char*)calloc( row, sizeof(unsigned char)); if(box[i] == NULL) exit(EXIT_FAILURE); } return box; } //引数では配列の先頭アドレスだけ渡す形にしたい void FreeByteArray2d(unsigned char** box){ //ここをどう書いたらいいかわからない }

  • 配列の動的確保

    No.847223 reallocについて No.847300 ポインタについて と質問させてもらい、御回答をいただき、理解した(つもりな)のですが、以下のことが実現できなくこまっております。 (以前の質問はこれを実現するために質問しました。) まず配列array[1][20]を用意します(つまり文字列最高20字格納できる要素数1個の配列を用意)。 そして動的にこの配列のサイズを変更して、なにか文字列を入力する毎に、代入するスペースを逐次確保したいわけです。(メモリが溢れない限りスペースを確保しまくる) そこでcallocやreallocの記述の仕方に困っています。 まず、callocについて char array[1][20]; char *pn, *pn2; pn = (char *)calloc(sizeof(array)/sizeof(char),sizeof(char)); このボイドポインタをキャストする部分にchar* と char** のどちらを使えばいいか、です。 そしてreallocについて、 if( (pn2 = (char *)realloc(pn, sizeof(array)*cnt)) == NULL ){ printf("メモリの確保失敗!\n"); exit(0); } pn=pn2; strcpy(pn[cnt],input); 【ただし、cntは毎回1づつ増加する。】 【inputはchar型の配列で、なんらかの文字列がはいっている。】 としているのですが、これもキャストの仕方がわかりませんし、strcpyで、セグメンテーションフォルトになります。構造体を使ったリスト形式も考えたのですが、reallocの使いかたを覚えたいのであえてこの形式で実現しようとしています。 結局どうしたいかというと、realloc部をforループさせて、cntを1ずつ増加させ、 pn[1][20] つぎは pn[2][20] つぎは pn[3][20] とどんどん増やしていきたいわけデス。 すこしわかりにくい説明だとおもいますが、不明点や、言い回しがオカシイ箇所があればご指摘下さい。

  • ファイル名を複数個配列で確保したいときどうすればいいですか?

    int i; FILE *fp[5]; //ここの宣言がわかりません char *(filename[5])={"1.txt","2.txt","3.txt","4.txt","5.txt}; for(i=0;i<5;i++) fp[i]=fopen(filename[i],"w"); のようなことをしたいのですが、ファイル名を複数個配列に格納するにはどのようにしたらいいんでしょうか? 回答お願いします。

  • STLで、vectorのファイルへの書き出し、読み込み。

    STLで、vectorのファイルへの書き出し、読み込み。 C++ の STL で vector をファイルに書き出し、読み込もうとしておりまして、まずは書き出しで躓いております。 vector<int> testvector; for (i = 0 ; i < 10 ; i++) testvector.push_back( i ); ofstream out("test.dat", ios::out | ios::binary); if (!out) return 1; out.write((vector<int>) testvector, sizeof(testvector)); out.close(); こんな感じのコードですと、 error: no matching function for call to ‘std::basic_ofstream<char, std::char_traits<char> >::write(std::vector<int, std::allocator<int> >, long unsigned int)’ /usr/include/c++/4.2.1/bits/ostream.tcc:173: note: candidates are: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::write(const _CharT*, std::streamsize) [with _CharT = char, _Traits = std::char_traits<char>] とのことです orz. どのようにすれば vector を書き出し、そして読み込むことができるのでしょうか。情報がありましたら是非お寄せください。

  • 配列の動的確保を関数化

    main()内でいくつかの配列を動的確保するとごちゃごちゃするので、 関数化してみました。しかし、下のプログラムではうまい事いきませ んでした。 #include<stdio.h> #include<stdlib.h> void array1d(int *box,int n) { int i; box=(int *)malloc(n * sizeof(int)); for(i=0; i<n; i++) { box[i]=0; } } main() { int *pol,i,n; printf("N pol\nN = "); scanf("%d",&n); array1d(pol,n); for(i=0; i<n; i++) { printf("[%d]=%d\n",i,pol[i]); } } 実行結果は [0]=-14646387 [1]=-1819410433 [2]=-224 array1d内では0を格納していますが、このようになりました。 どのようにすれば 0になるでしょうか? 回答よろしくお願いします。

  • new int[変数]で確保しても良いんですか?

    Javaでの配列の確保の方法です。 int size = 100; int[] array = new int[size]; のような確保の方法はどの環境・コンパイラでも思い通りの動作をしてくれますか? C言語では、このような書き方で確保することはできなかったので、Javaでは可能なのか心配で質問しました。 「動的」という意味がまだ完全にわかっていないのですが、上記のような変数の確保は、動的とはいえないのですか?sizeの値をユーザーから受け取れば、確保する大きさはいつも違うようになると思うのですが・・・。 ちなみに下記のようなプログラムで配列の確保を使おうとしています。 static int[] toIntArray(String[] strs){   int[] array = new int[strs.length]; // ←ここで 確保しています。   for(int i = 0; i < strs.length; i++){    array[i] = Integer.valueOf(strs[i]).intValue();   }   return array; } 上記のプログラムはStringの配列からintの配列に変換することを目的にしています。

    • ベストアンサー
    • Java
  • 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)] 分かる方、回答お願いします。

専門家に質問してみよう