- ベストアンサー
文字型配列の有効期間
char 型配列の有効期間について教えてください。 例えば、 char* p=(char*)malloc(sizeof(char)*10) などで、動的に配列を確保した場合、必ずfree()で、 開放する必要があると思うのですが、 char[]="Hello"; char* p; p=char; p=null; char=null; とした場合、pとcharが指していた”Hello"の領域は 自動的に開放されるのでしょうか?また、開放される としたらそれは、pおよびcharにnull が代入された 時点でしょうか? どうぞよろしくお願いいたします。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
開放されません。 文字列リテラルは固定領域に取られます。malloc等で動的に確保した領域とは全く異なります。
その他の回答 (1)
- PG_RankB
- ベストアンサー率40% (12/30)
初めまして、おおよそ中級者成り立て程度の者です。 内容を見た感じ、C++には触れていないようですので、C言語である事を前提でお話します。 動的に配列を確保した場合(mallocやcalloc)、必ずfree()で開放する必要がある。 と言うのは正しい認識です。 ただ、 char[]="Hello"; char* p; p=char; p=null; char=null; がよく分かりません。 char=nullだけ見ても、 charはデータ型であり、予約語ですので、左辺に適用させる事は言語仕様上、不可能です。 他にも何点かありますが、伏せておきます。 ともかく、コンパイルエラーは先ず間違いないと思いますが・・・ このコードから汲み取れる内容として、 pに10バイトで動的にメモリ確保を行い、何らかの参照なり書き込みを行い、最後にpにnullを代入した時に、pが指した内容は自動解放されるのか。 またそのタイミングは?と言う認識で宜しいでしょうか? 一応、それを前提でお話しますが、(違っていたらすみません)pにnullを代入するだけなら、構文上は合っていますので、コンパイルは大抵通ると思います。 ですが、pは普通に宣言されたポインタでは無く、"mallocによって作られた領域の先頭アドレス"を格納するポインタになります。 普通に宣言したローカル変数などは、メモリの中でも、スタックと言うエリアに保持されます。 スタックにある変数は、ブロックを抜けた瞬間に自動的に解放されるように出来ていますが、mallocなどで宣言した内容は、メモリの中で、ヒープと呼ばれる空間に、指定したサイズで領域が取られます。 このヒープ領域は、ブロックを抜けても自動で解放される事は無いと考えて下さい。 mallocでpを宣言した場合、pには、"ヒープ領域内のどこかに10バイトの大きさで作られたエリア"の、先頭アドレスが代入されています。 ここでpにnullを代入すると、pの指す位置が初期化されますので、その後pを使って、先ほどのヒープ内10バイトエリアを参照する事は出来なくなります。 と言うより、事実上100%、参照出来なくなってしまいます。 ヒープ内のどこからの10バイトだったのか。その、どこから。と言う位置を、唯一pが示していたのですから、pの内容をnullで潰してしまえば、当然10バイトエリアは行方不明になります。 さらに、その10バイトはヒープ内にあり、ヒープに作られた領域は、ブロックが終わっても、あるいはその実行ファイルを終了しても、解放はされません。 つまり、その10バイト内に"Hello"と書き込んでいたなら、ずっと、その10バイトの空間には"Hello"と残ってしまう事になります。 free()は、そのヒープ領域にある10バイト自体を空にして、使える状態。つまり、解放を行います。 この場合、 free(p); とすると思いますが、pにnullが代入されてしまっていたら、free()は一体どこから解放して良いのか分からなくなってしまいます。 場合によっては、システムにダメージを与える可能性もあります。 pを解放するタイミングは、そのpと言う変数自体が、メモリ上のどこにあるのかで決めてください。 グローバルでpを宣言し、どこかでmallocしたならば、mallocした後且つ、main()が終わる前なら、どこでもfree()できます。 pがどこかの関数内で、ローカルのポインタ変数として宣言された物なら、その関数が終わる前に、free()で解放する必要があります。 長々と分かり辛くて申し訳無いです。 上級者の皆様、ここ違うだろ、と言う指摘がありましたら、フォローをお願い致します。
お礼
コードが間違いだらけですみません。 言いたかったのは、 char f[]="Hello"; char* p; p=f; p=null; f=null; ということでした。 >>スタックにある変数は、ブロックを抜けた瞬間に 自動的に解放される ここでいう p や f はブロックを抜けると消失し、 "Hello"は固定領域として残るということですね。 コードミスにもかかわらず詳しく説明してくださり ありがとうございす。
お礼
そうですか。どのポインタからも参照され なくなっても残るんですね。Static変数などと 同じような静的な扱いということですね。 よく理解できました。ありがとうございます。