• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:動的なメモリ確保の仕方)

動的なメモリ確保の仕方

このQ&Aのポイント
  • ユーザーが入力した任意個数のデータを受け取り、平均や標準偏差を求めるプログラムを作成するための、効率的なメモリ確保方法を探しています。
  • 現在考えられる方法として、あらかじめ限界サイズの配列を用意する方法と、ポインタとmalloc関数を使用して動的にデータ領域を確保する方法がありますが、いずれも効率的ではないと感じています。
  • 効率的なメモリ確保方法について情報がなかなか見つからないため、良い方法をご存じの方は教えていただきたいです。

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

  • ベストアンサー
noname#210530
noname#210530
回答No.3

例えば以下のような構造体を用意します。 {  1000個のデータ用配列  データ有効数(0-1000)  1000個埋まった時の次の構造体アドレス } 入力データが1000増える毎に、構造体1つ分をmalloc()してチェーン状に繋げれば、程々のメモリ効率が実現できます。 適当に1000という値で説明しましたが、調整すればそこそこ使えると思います。

ghatake
質問者

お礼

ご回答ありがとうございます。 ご提案いただいた方法は、 ■既に検討中の方法に対して、技術的追加要素がほぼ無く、 ■ただn個の配列にするだけで、メモリ使用における   ポインタ情報の比率をn分の1にできる(効果を得やすい!) の2点で優れていると感じました。 使わせていただきたいと思います。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (4)

  • don_go
  • ベストアンサー率31% (336/1059)
回答No.5

>「入力されたデータをメモリ容量限界まで >保存可能にする。」 >なかなかそれという情報にネットで出会え >ていない状態です。 それをしてしまうと、プログラムがデータを 処理する為の作業領域用のメモリも無くなる のでプログラムとしては意味の無い物になる だけだからです。

全文を見る
すると、全ての回答が全文表示されます。
回答No.4

realloc で必要な分だけ領域を広げれば次データ用のポインタは不要になりますが、 次データのポインタを使う方式はデータが連続している必要がないのに対して 次データのポインタを使わない方式では全データが連続している必要があるので、 少ないメモリを効率的に使う場合には必ずしも有効ではありません。 C++ と 標準テンプレートライブラリ(STL) が使える環境であれば vector や list 等のコンテナが使えますから、 自作せずにそれらを使うのが良いかと思います。

ghatake
質問者

お礼

ご回答いただき、ありがとうございました。 説明不足で申し訳ありませんが、C言語限定のつもりでした。 reallocをする方法は考えておりませんでした。 ただこの方法の場合、その他の処理によって [--既確保分--][何か別の処理用] とたまたまなってしまうと、メモリ容量限界に関わらず、 「連続した領域は確保できなかった」ということで、 NULL返しになってしまわないでしょうか? >C++ と 標準テンプレートライブラリ(STL) が使える環境であれば >vector や list 等のコンテナが使えますから、 >自作せずにそれらを使うのが良いかと思います。 今回は仕組みを学ぶことを目的としていましたので、 コンテナの利用は控えたいと思います。

全文を見る
すると、全ての回答が全文表示されます。
  • don_go
  • ベストアンサー率31% (336/1059)
回答No.2

0x7FFFFFFF=2,147,483,647 >ユーザーが入力した任意個数 21億件のデータを1人で入力しようとすれば 日が暮れても終わりません。 複数の人を使って入力を行い、ファイル又は データベース渡しで受け取ったデータを使う のをお薦めします。 その場合、メモリ上に配列を持つ必要はあり ません。

ghatake
質問者

補足

ご回答ありがとうございます。 >複数の人を使って入力を行い、ファイル又は >データベース渡しで受け取ったデータを使う >のをお薦めします。 おっしゃることはごもっともですが、 データ構造・管理に関する設計上の問題はとりあえず棚上げし、 「入力されたデータをメモリ容量限界まで保存可能にする。」 ということについて、どういう実現方法があるのかを検討しておりました。

全文を見る
すると、全ての回答が全文表示されます。
回答No.1

残念ながら「ありません」 メモリ内に確保できないほどになったらDatabaseにぶち込みますし。

ghatake
質問者

お礼

ご回答ありがとうございます。 >メモリ内に確保できないほどになったらDatabaseにぶち込みますし。 はい、通常それが当然の方法かと思います。 「残念ながら「ありません」」なことは、本当に残念ですが、 あきらめがつきました。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

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

    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; }

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

    アドレス格納のための二次元配列のメモリ動的確保 二次元配列のためにメモリを動的確保しなければならないのですが、 その配列に格納したいものが 「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 あとこれだけ通ればコンパイルが通るんです!!!!! たぶん(笑)

  • C言語のメモリ領域確保

    ポインタ変数ををmain関数で宣言し、関数test()にて必要分だけ領域確保してそのアドレスをmain関数のポインタ変数に渡して利用することは可能でしょうか。 (サイズのわからないテキストデータを、十分に大きな配列に入れるのではなく、関数でメモリを動的確保して無駄の無い配列に入れたい等) C言語ではやはり無理で、構造体のリストにするのが一番でしょうか。 初歩的なことで申し訳ありませんがどなたかお願いいたします。

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

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

  • 構造体の動的確保について

    ある変数により動的確保を行いたいのですが、構造体中の変数に対して動的確保はできるのでしょうか? struct data{ int i[30]; /*←ここの配列を動的に確保したい*/ double d[40]; /*←ここの配列を動的に確保したい*/ }data1[10]; よろしくお願いします。

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

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

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

    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: 配列または、ポインタでない変数に添字が使われました。 というエラーがでます。動的メモリの確保の仕方がまずいのでしょうか? どなたか教えて頂けますでしょうか?よろしくお願いします。

  • メモリ動的確保について

    こんにちはです。 メモリの動的確保なのですが、 typedef struct DATA{ char name[256]; char pass[256]; int money; }BANK; void insert(BANK *p,int max); int main(){ int i; size_t st; BANK *person; person = (struct DATA *)malloc(sizeof(struct DATA)); //person = (struct DATA *)malloc(5); if(person == NULL){ printf("確保失敗\n"); exit(-1); } //memset(person,'\0',sizeof(struct DATA)); と、言う風に、記載ソースは途中ですがメモリをとりました。 mallocの後ろの部分ですが、sizeof(struct DATA)と5ではどうちがうのでしょう??2通りともコンパイルエラーはないです。 5は動的に最大5までとるって事はわかるのですが、struct DATAの方はいくつとるのです??いくつもで入力次第です? そして、動的したのにたいしてmemsetしたら実行エラー(コンパイルは通りました)おきました。動的にたいしてmemはダメなのでしょうか? アドバイスいただけたらありがたいです。宜しくお願いいたします。

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

    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); 大変申し訳御座いませんが、 ご指摘・ご指導願いませんでしょうか? どうか宜しくお願い致します。

  • 構造体配列のメモリ確保

    以下のようなプログラムを作りました。 make_mem関数のなかで構造体のメモリを確保し、 データを代入しています。 しかし、mainに返ってくると値が代入されていません。 よく調べてみると、mainで宣言してあるdataのアドレスが 変更されていません。 どのようにすれば、meake_memoのなかでメモリ確保し、 データを代入できるのでしょうか? 教えてください。 実際の使用しているプログラムはmake_memoのなかで DBを開き、そのデータを配列に代入しているので、 main関数の中では配列の大きさがわかりません。 #include <stdio.h> typedef struct { int a; int b; }DATA; int make_mem(DATA *data){ int i; data=(DATA *)calloc(10,sizeof(DATA)); printf("calloc %p\n",data); for (i=0;i<10;i++){ data[i].a = i; printf("data[%d].a = %d\n",i,data[i].a); } return 0; } int main(int argc,char *argv[]){ DATA *data; int i; printf("before %p\n",data); make_mem(data); printf("after %p\n",data); for (i=0;i<10;i++){ printf("data[%d].a = %d\n",i,data[i].a); } return 0; }