- ベストアンサー
mallocについて
まだ初心者で分からないところがあるのですが 例えば char *Buf; Buf=(char *)malloc(256); free(Buf); としますよね? それを、 グローバル変数(?)で「char *Buf」として 処理の途中途中で Buf=(char *)malloc(*適当) を、何回も使い 最後の解放されるときに free(Buf) (*適当 は、適当な数値) を使う事は大丈夫でしょうか? それとも、ちゃんとメモリを割り当て(?)たら 使ったあとすぐに、メモリを解除しなければ ならないのですか? よろしくお願いしますm(_ _)m
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
基本的には、#2さんのとおりですが・・・ ちょっと気になったので補足を。 たとえば、mainの先頭で、 Buf=(char *)malloc(十分大きな値) を実行して、このメモリーを、その後、プログラム全域でずっと使い続ける。という使い方はありです。メモリーの確保というのは、意外と重たい処理なので、開放と確保の作業の繰り返しがあまりにも多いときには、この手を使用することがあります。 しかし・・・ 決して、同じBufに対して、freeを実行することなくmallocを2回以上実行してはいけません。一度、グローバル変数Bufに保管したメモリー領域は、freeを実行するまでずっと有効です。そこに、もう一度、 Buf=(char*)malloc(適当) を実行すると、この文を実行する前に確保されていたメモリーが迷子になります。そこに確保したメモリーは相変わらず確保されたままあるのですが、アドレスをメモしておいたBufを上書きしたので、もうそこにアクセスできなくなったと言う状態です。(freeに与える引数にする値も失われたので、もう開放することもできません) この状態を、メモリーリークと称します。Cのプログラムでよく発生する「バグ」です。何度も繰り返して、迷子のメモリーの量が多くなると、メモリー不足でプログラムの続行ができなくなる・・・という結果になります。 注意してくださいね。
その他の回答 (3)
- symgt
- ベストアンサー率56% (68/120)
処理の途中で確保したメモリのサイズを変更したいのであれば realloc()を使用しましょう。 char *p; p = (char *)malloc(10); p = (char *)realloc(p, 20); p = (char *)realloc(p, 30); free(p);
お礼
あ、ちゃんと書いておけばよかったですね... メモリのサイズを変更したのではなく ただ単にメモリを初期化(?)したかっただけなのです だけど、reallocのことを忘れてて 丁度良く思い出せました ありがとうございますm(_ _)m
- mcWalker
- ベストアンサー率69% (27/39)
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 という名前でメモリ領域を確保して置き、 メモリ不足に陥ると、ここを使って状況を表示するとか していました。
お礼
あー、なるほど、そういうやりかたもあるんですねぇ forRainyDay、なんかこういう系統好きなんで 覚えておきます♪ ありがとうございますm(_ _)m
- tatsu99
- ベストアンサー率52% (391/751)
>グローバル変数(?)で「char *Buf」として >処理の途中途中で Buf=(char *)malloc(*適当) >を、何回も使い >最後の解放されるときに free(Buf) >(*適当 は、適当な数値) >を使う事は大丈夫でしょうか? 前に割り当てられたメモリが解放されないで残ります。 これが、思わぬバグを招くことになります。 >それとも、ちゃんとメモリを割り当て(?)たら >使ったあとすぐに、メモリを解除しなければ >ならないのですか? 必ずそのようにしてください。
お礼
なるほど、...わかりました ありがとうございますm(_ _)m
お礼
長い解答ありがとうございます あ!また別なんですが、これで不思議な謎が解けました! どうしてテストを繰り返してる最中に プログラムがおかしくなるのか、わからなかったのですが こういうことだったんですね いろいろと参考になりました ありがとうございますm(_ _)m