• 締切済み

C言語 mallocとfreeについて

mallocとfreeを何度も繰り返していると、メモリがどんどん増えていき、最終的にはプログラムが止まってしまいます。 いくつかのページでメモリ確保を繰り返すとメモリをかなり食ってしまうと書いてありました。 これに対する解決策をご存知の方いらっしゃいましたら教えてください。 よろしくお願いします。

みんなの回答

  • crew21
  • ベストアンサー率26% (58/222)
回答No.4

No.2です。 これはNGだよ。 for文使ってm回(28561回)のmalloc()をしてるんだよね。 それに対して、free()はfor文を出たあとの1回だけでしょ。 てことは、28561回目に確保したメモリだけは解放されるけど、1~28560回目までに確保しまくったメモリは解放されない(中に浮いたまま)ということになるからね。 当然パンクします。 free()をfor文の中に入れて、その確保したメモリが不必要になった都度free()するといいんじゃないかな。要はmalloc()とfree()が対になるようにするということ。 そうすればメモリの確保と解放のバランスというか論理性が取れて、少なくとも質問欄に書いたようなことはなくなると思うよ。 ※1回ごとのメモリ確保量がどれくらいか、面倒だから見てないけど、それは気を付けてください。  いくらmalloc()とfree()のつじつまがあってたって、一度に100MBとか確保しようとしたら、環境にもよるけど、まずダメだからね。 まあ、コードを見る限り構造体一つ分のメモリを確保しようとしているだけだから、常識的に考えてOKだとは思うけど。

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.3

rもqもm回mallocしてますが、解放は最後の1回だけしかしてませんのでメモリ補足になるのは当たり前だと思います。 rとqを配列にしてループ回数格納するか、ループの範囲が間違ったプログラムだと思います。

  • crew21
  • ベストアンサー率26% (58/222)
回答No.2

そんなことあり得ないとおもうけど... ちょっとここに、具体的にどんな感じでmallocとfreeを使ってるか書いてみては? あんまり長いと読む気なくなるから、不要なコードは削除して20行程度で。 よく新人さんである話だけど、 char *a = (char *)malloc(100); とかやっといて、 free( *a ); とかやってない? 或いは free( &a ) とか。 もしやってるとすると全然おかしなところを解放していることになるよ。

pirlo_kaka
質問者

お礼

crew21様 ご回答ありがとうございます. コードの方,書かせていただきます. void dijkstra(struct edge *E, struct edge *T, float *dstar, int n, int m, int m2, int st){ struct cell *adjlist[N]; /* グラフの隣接リスト */ struct cell *r, *q, *p; m=28561; for(i=0; i<m; i++){ v1=E[i].end1; v2=E[i].end2; r=(struct cell *)malloc(sizeof(struct cell));   r->adj=v2; r->edge=i; r->next=adjlist[v1]; adjlist[v1]=r; q=(struct cell *)malloc(sizeof(struct cell)); q->adj=v1; q->edge=i; q->next=adjlist[v2]; adjlist[v2]=q; } /*ここに取得したポインタを使ったダイクストラの計算が入ります.*/ free(r); free(q); return; } このようなコードになっています. この関数を4回程度計算すると,メモリがいっぱいになってしまいます. m=312の時は,300回以上繰り返し計算をすることができました. やはり,mの値が大きく,負荷が大きいためでしょうか. それとも,やはりメモリの開放がだめですか.

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.1

小さなサイズと大きなサイズのmallocを繰り返していて、mallocした順に解放していないとメモリ不足になる可能性はあります。 環境が書かれていませんが、Windowsやパソコン用のLinuxであると仮定すると通常はありえないと思いますが、マイコンであれば十分にありえます。 もし、WindowsやLinuxであればmallocしたまま不要になってもfreeし忘れているか、システム的に無理があるほどメモリを利用していると思われますのでメモリの利用の仕方を再設計したほうが良いでしょう。 マイコンであれば、自分でメモリ管理関数を作って小さいサイズのメモリ確保はmallocに頼らないほうが無難です。 自分でガベージコレクトという手もありますが、遅くなるのでお勧めしません。

pirlo_kaka
質問者

お礼

zwi様 ご回答ありがとうございました. windowsを使っていてfreeもできていると思うのですが,大きなメモリサイズを確保させようとしているのが負荷がかかっているようです. 今はコマンドプロンプトからfor /L %d in (0,1,9999) %d do AAA.exeの文を使っています. 計算を細分化して繰り返し行い,システムに負荷がかからないようにしてみました.

関連するQ&A

  • mallocとfree

    struct list *p; /* 記憶領域の確保 */ if ((p = (struct list *) malloc(sizeof(struct list))) == NULL) { printf("malloc error\n"); exit(1); } とサンプルプログラムがあるのですが、if分の意味がわかりません。 また、mallocを使った場合freeで開放とあるのですが、 どういう意味なのかわかりません。 よろしければ、上記2つの点について教えてください。

  • mallocの書式について

    初心者です。プログラム上でメモリを確保するmallocという関数がありますが書式がいまいち良くわかりません・・。   戻り値? * malloc(確保する型 * 確保する数) のように書いてますけどmallocの前のはやはり戻り値?そのまえの*は?いまいちわかりません。よろしくお願いします。

  • malloc関数 free開放とはなんですか?

    malloc関数を用いてメモリを確保した後、 必ずfreeで開放を行わなければならないですよね? この開放とはどういう意味なのでしょうか?

  • mallocで確保したメモリをfree解放する必要

    当方、C言語を勉強中です。 mallocで確保しておいたメモリをfreeで必ず解放するようにと教わりました。 freeで開放しないことをひどく野蛮な言葉で例えられたのですが、それほどまでに必要である実感が実はあまりありません。 ファイルポインタでファイルを開いているときに、プログラムが終了すると開いているファイルを自動的に閉じるように、プログラムが終了すると自動的に解放されるものと思っていたのですが、やはりこちらはプログラム終了後も確保されたままになってしまうのでしょうか。 また、解放しないことによるデメリットで、メモリを圧迫する以外にはなにがあるのでしょうか。 ご教授おねがいします。

  • c言語のmalloc関数、またrealloc関数

    c言語のmalloc関数は確保するメモリの領域を、配列としてのみしか処理出来ないのですか。 つまり、malloc関数で確保したメモリの領域を変数、また多次元配列、また構造体としては処理出来ないのでしょうか。 c言語のrealloc関数は以前の確保したメモリの領域から、確保し直したメモリの領域の場所が変わるかもしれないという事ですが、この場合の場所が変わるという意味は、メモリの領域のアドレスが変わるという事でしょうか。 また、以前の確保したメモリの領域に代入していたデータが使用出来なくなるという事でしょうか。

  • C/C++言語のメモリについて

    C言語でメモリを2種類?に分けると、スタックとヒープがあります。 ヒープは mallocなどで確保し、freeで解放しますがスタックは解放する必要がありません。 そのスタックは通常、何バイトまで可能なのでしょうか? あと関数外のファイルの先頭に int[1000000];とした場合、このメモリはmallocで確保していませんが、 どこに作られるのでしょうか? 私のパソコンはメモリが2GBでWindows2000ですが、CやC++で最大、何バイトまでメモリが使えますか? また、一番多くメモリを確保できるなら、OSはなんでも構いません。 解釈等も間違っていたらご指摘していただきたいです。

  • ポインタ&mallocで困っています(C言語)

    あるローカル関数内でポインタを宣言し、mallocで領域確保します。そのポインタをグローバルで宣言したポインタに渡します。そしてローカル関数を抜ける。 その後、他のローカル関数内で、そのグローバルなポインタを呼び出して、ポインタの実態を参照しているのですが、プログラムが進むうちにそのグローバルポインタの実態の一部が書き換わってしまいます。どういう原因が考えられるでしょうか?

  • メモリ操作関数『malloc(),free()』

    /*10バイトのメモリ領域を確保し、その領域に文字列"Allocate"を代入せよ。*/ /*ただし、確保した領域は、プログラム終了までに開放すること。*/ #include<stdio.h> #include<stdlib.h> void main(void) { char *ptr; ptr = (char *)malloc(10); printf("Allocate\n"); free(ptr); } 今、ライブラリ関数を勉強しています。 この問題をとりあえず作ってみて、実行も成功したのですが、10バイトのメモリ確保の数値を変えても、何も変わらないため本当に問題の要求どおりのプログラムが作れているのか謎です。 間違っているなどのアドバイス宜しくお願いします。

  • mallocについて

    mallocについて 現在C言語でプログラムをかいているのですが、原因不明のエラーが出て困っています。 それはmallocによる動的メモリ確保を行ったとき、 (float *)malloc(sizeof(float)*200)の場合大丈夫ですが、 (float *)malloc(sizeof(float)*320)ではエラーが出てしまうのです。 しかし (float **)malloc(sizeof(float*)*640)とした場合エラーは出ませんでした。 これは何が原因でエラーが出ているのでしょうか? ちなみにコンパイルはできており、実行したとき プログラム名(7637) malloc: *** error for object 0x100ff7a08: incorrect checksum for freed object - object was probably modified after being freed. *** set a breakpoint in malloc_error_break to debug というエラーがでます。

  • mallocについて

    vine linux 3.0上でgccを使い下記のようなプログラム(読みにくいプログラムで申し訳ありません)を作成してみました。無事コンパイルも通りメモリも確保出来ました。 しかし、このプログラムを2つ起動しそれぞれでメモリを確保するとおかしな事が起きるのです。どういう症状かと言うとプログラム1もプログラム2も同じ先頭アドレスを確保しているのです。 例) プログラム1 keep memory size : 11 address : 0x8049700 プログラム2 keep memory size : 11 address : 0x8049700 なぜこのような事が起こるのでしょうか? ご教授宜しくお願いします。 #include <stdio.h> #include <stdlib.h> main(int argc, char *argv[]) { int size; unsigned int *p; char buf; size = atoi(argv[1]); printf("keep memory size : %d\n", size); p = (unsigned int *)malloc(size); printf("address : %p\n", p); scanf("%c", &buf); free(p); }