ページ 11

ポインタの配列を動的に確保する

Posted: 2013年7月06日(土) 13:48
by もみじふぇにっくす
こんにちは先日は失礼しました。データを保持するためにポインタの配列をつかっているのですが配列を大きくすると動作を停止してしまいます。スタックには2MBまでしかデータが入らないヒープにするためにmallocを使えといわれましたが、ポインタの配列を動的にmallocする方法がわかりません。どうすればint function(char *buf[]);の引数のbufを動的に確保できるようになりますか?
nt main(void)
{
int i,tablesize;
char ret;
char *buf[50000000000];
FILE *fp;
fp=fopen("in.txt","r");

for(i=0;i<1023;i++)buf=(char*)malloc(sizeof(char)*1024);
//何かの処理をする
function(buf);
}

Re: ポインタの配列を動的に確保する

Posted: 2013年7月06日(土) 13:55
by softya(ソフト屋)
もうひとつの方の質問で、解決チェックした上に投稿してくださいね。質問が解決したことがわかりませんので。

それと今回ので 50000000000 * 1024を確保したいのか目標サイズを教えて下さい。
50000000000 だとcharでも49GBなので物理的に普通のPCではmallocであろうと確保不可能ですけどね。
あと、なぜこういう確保が必要なのかやりたい事を教えて下さい。たぶん設計方針が間違っていると思います。

Re: ポインタの配列を動的に確保する

Posted: 2013年7月06日(土) 14:15
by もみじふぇにっくす
40万行のテキストファイルを読み込もうとしています.一行は200バイトあればだいじょうぶだとおもいます.ファイル自体は15メガバイトくらいあります。405000個の配列を宣言すると動作が停止してしまいます。


int main(void)
{
int i,tablesize;
char ret;
char *buf[405000];
FILE *fp;
fp=fopen("in.txt","r");

i=0;
buf=(char*)malloc(sizeof(char)*201);
while(fgets(buf,200,fp)!=NULL){
printf("%d\n",i);
i++;
buf=(char*)malloc(sizeof(char)*201);
}
tablesize=i;

}

Re: ポインタの配列を動的に確保する

Posted: 2013年7月06日(土) 14:36
by へにっくす
もみじふぇにっくす さんが書きました:405000個の配列を宣言すると動作が停止してしまいます。
405000個の配列変数も、mallocで確保すればいいんでない?

コード:

char **buf = (char**)malloc(sizeof(char*) * 405000);
int j;
for ( j = 0; j < 405000; j++ ) {buf[j]=NULL;} // NULLで初期化
ちなみに、確保したメモリはちゃんとfreeを使用して解放してね。

コード:

for (j = 0; j < 405000; j++) if ( NULL != buf[j] ) {free(buf[j]);}
free(buf);
何行でも読めるようにする場合は、テキストファイルを一度舐めまわして、何行あるか(\nが何個あるか)を取得し、それを405000の代わりにして実際に読み込むようにします。

Re: ポインタの配列を動的に確保する

Posted: 2013年7月06日(土) 14:46
by h2so5
へにっくす さんが書きました: for ( j = 0; j < 405000; j++ ) {buf[j]=NULL;} // NULLで初期化[/code]
ちなみに、確保したメモリはちゃんとfreeを使用して解放してね。

コード:

for (j = 0; j < 405000; j++) if ( NULL != buf[j] ) {free(buf[j]);}
free(buf);
NULLチェックする意味はないのでもう少し簡潔に書けます。

コード:

for (j = 0; j < 405000; j++) free(buf[j]);
free(buf);

Re: ポインタの配列を動的に確保する

Posted: 2013年7月06日(土) 14:53
by へにっくす
h2so5 さんが書きました:NULLチェックする意味はないのでもう少し簡潔に書けます。
free(NULL);ってできましたっけ。。
まあプロセスを抜ける後始末の処理なのでいいのかもしれませんが。

Re: ポインタの配列を動的に確保する

Posted: 2013年7月06日(土) 14:58
by softya(ソフト屋)
200文字が入るバッファに読み込んで、strlenでサイズを調べた後mallocしたほうが効率は良くなりますね。
あとは皆さんの言う通り、405000個のポインタ配列を先に確保しておくのがひとつの方法で、リスト構造というのを使ってどんどん拡張していくのが別の方法です。

Re: ポインタの配列を動的に確保する

Posted: 2013年7月06日(土) 16:07
by もみじふぇにっくす
みなさんありがとうございます。ポインタのポインタをつかった方法でうまくよみこめました。リスト構造は難しそうなのでもうすこし詳しくなってからつくってみます

int main(void)
{
long i,tablesize,reta;
char ret,findtxt[1024];
// char *buf[400000];
FILE *fp;
fp=fopen("data.txt","r");
char **buf = (char**)malloc(sizeof(char*) * 405000);
long j;
for ( j = 0; j < 405000; j++ ) {buf[j]=NULL;} // NULLで初期化

i=0;
buf=(char*)malloc(sizeof(char)*201);
while(fgets(buf,200,fp)!=NULL){

i++;
buf=(char*)malloc(sizeof(char)*201);
}
tablesize=i;
}

Re: ポインタの配列を動的に確保する

Posted: 2013年7月06日(土) 16:10
by ISLe
外部変数(関数の外で宣言する変数)ではいけないのですかね。

Re: ポインタの配列を動的に確保する

Posted: 2013年7月07日(日) 21:55
by みけCAT
関数内でstaticをつけて宣言するという方法もあったと思いますが、環境依存でしょうか?