• ベストアンサー

mallocについて

まだ初心者で分からないところがあるのですが 例えば char *Buf; Buf=(char *)malloc(256); free(Buf); としますよね? それを、 グローバル変数(?)で「char *Buf」として 処理の途中途中で Buf=(char *)malloc(*適当) を、何回も使い 最後の解放されるときに free(Buf) (*適当 は、適当な数値) を使う事は大丈夫でしょうか? それとも、ちゃんとメモリを割り当て(?)たら 使ったあとすぐに、メモリを解除しなければ ならないのですか? よろしくお願いしますm(_ _)m

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

  • ベストアンサー
  • mitoneko
  • ベストアンサー率58% (469/798)
回答No.4

 基本的には、#2さんのとおりですが・・・  ちょっと気になったので補足を。  たとえば、mainの先頭で、  Buf=(char *)malloc(十分大きな値)  を実行して、このメモリーを、その後、プログラム全域でずっと使い続ける。という使い方はありです。メモリーの確保というのは、意外と重たい処理なので、開放と確保の作業の繰り返しがあまりにも多いときには、この手を使用することがあります。  しかし・・・  決して、同じBufに対して、freeを実行することなくmallocを2回以上実行してはいけません。一度、グローバル変数Bufに保管したメモリー領域は、freeを実行するまでずっと有効です。そこに、もう一度、  Buf=(char*)malloc(適当)  を実行すると、この文を実行する前に確保されていたメモリーが迷子になります。そこに確保したメモリーは相変わらず確保されたままあるのですが、アドレスをメモしておいたBufを上書きしたので、もうそこにアクセスできなくなったと言う状態です。(freeに与える引数にする値も失われたので、もう開放することもできません)  この状態を、メモリーリークと称します。Cのプログラムでよく発生する「バグ」です。何度も繰り返して、迷子のメモリーの量が多くなると、メモリー不足でプログラムの続行ができなくなる・・・という結果になります。  注意してくださいね。

dinowave
質問者

お礼

長い解答ありがとうございます あ!また別なんですが、これで不思議な謎が解けました! どうしてテストを繰り返してる最中に プログラムがおかしくなるのか、わからなかったのですが こういうことだったんですね いろいろと参考になりました ありがとうございますm(_ _)m

その他の回答 (3)

  • symgt
  • ベストアンサー率56% (68/120)
回答No.3

処理の途中で確保したメモリのサイズを変更したいのであれば realloc()を使用しましょう。 char *p; p = (char *)malloc(10); p = (char *)realloc(p, 20); p = (char *)realloc(p, 30); free(p);

dinowave
質問者

お礼

あ、ちゃんと書いておけばよかったですね... メモリのサイズを変更したのではなく ただ単にメモリを初期化(?)したかっただけなのです だけど、reallocのことを忘れてて 丁度良く思い出せました ありがとうございますm(_ _)m

  • mcWalker
  • ベストアンサー率69% (27/39)
回答No.2

tatsu99 さんの応えが基本ですが、global で、 テーブル類を固定長で、沢山定義するようなら、 main() の最初に確保して、出口で必ず解放する のも手です。よく見る方法は、main() の出口に cleanup: というラベルを付け、エラーなどの場合 全てそこへ goto させ、cleanup: で解放するわけ です。Cでは goto は嫌われますが、これも手です。   領域用のポインタは必ず初期値を NULL にして   おいて出口で NULLでなければ解放するとか、   逐次解放したら即 NULL にするとかして解放   洩れを防ぎます。 全部で 100 x 5 の領域が必要なら、500 で取って、 先頭+100, 先頭+200、のポインタを使う手もあります。 malloc(), free() を繰り返すと断片化が起きるの 防げます。(断片化防止には GlobalAlloc() などの API を MOVEABLE で使う手もあります。Mac なら、 NewHandle()) 蛇足ですが、メモリの少ない時代には、エラー処理用に forRainyDay という名前でメモリ領域を確保して置き、 メモリ不足に陥ると、ここを使って状況を表示するとか していました。

dinowave
質問者

お礼

あー、なるほど、そういうやりかたもあるんですねぇ forRainyDay、なんかこういう系統好きなんで 覚えておきます♪ ありがとうございますm(_ _)m

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.1

>グローバル変数(?)で「char *Buf」として >処理の途中途中で Buf=(char *)malloc(*適当) >を、何回も使い >最後の解放されるときに free(Buf) >(*適当 は、適当な数値) >を使う事は大丈夫でしょうか? 前に割り当てられたメモリが解放されないで残ります。 これが、思わぬバグを招くことになります。 >それとも、ちゃんとメモリを割り当て(?)たら >使ったあとすぐに、メモリを解除しなければ >ならないのですか? 必ずそのようにしてください。

dinowave
質問者

お礼

なるほど、...わかりました ありがとうございますm(_ _)m

関連するQ&A