• ベストアンサー
  • 暇なときにでも

ポインタについて

  • 質問No.3569822
  • 閲覧数85
  • ありがとう数4
  • 気になる数0
  • 回答数5
  • コメント数0

お礼率 54% (88/162)

C言語では
char *p;
と宣言しておいてそのポインタに
p = "ABC";
というように指定できると思います。
参考URL
http://www9.plala.or.jp/sgwr-t/c/sec10-3.html

このようにしてポインタを使用した場合、freeで開放する必要はあるのでしょうか。

配列で文字列を指定した場合
char str[] = "ABC";
スタック領域に確保されるので、宣言したメソッドが終わった場合、自動的に開放されると思いますが、malloc等でヒープ領域にメモリを確保した場合、freeで開放されるまではメモリ上に残っていると思います。

動きを見てみると、
char *p;
p = "ABC";
もメソッドが終わってもメモリ上に残っているように思えるのですが、
開放する必要があるのでしょうか。

上記のような指定の仕方は使わなければいいだけなのですが、
気になってしまいました。
変な質問ですいませんが、宜しくお願いします。

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

  • 回答No.4
  • ベストアンサー

ベストアンサー率 37% (189/502)

開放する/しない、については他の回答者さんの通りです。

「p = "ABC";確保されるとするとこの段階で確保されると思うのですが」

正確に言えば、確保されるのはこの文が実行される時でなく、プログラムの最初から既に確保されています。

int i = 1; とか
char *p = "xyz";

とかで指定された「定数」はコンパイル時に認識され、プログラムの「定数領域」(正確には定数領域という呼び方はされていませんが、ここではコンパイラが検出した定数が集められた領域のこととします)に集められています。

例えば、Unix (Linux) では strings というコマンドがあって、プログラムの中に埋め込まれている文字列定数をプリントすることができます。ので、質問者さんのプログラムも "strings a.out" とすると沢山の文字列の中に "ABC" という文字列が表示されるハズです。

勘違いされているのは、

char *p; //定義
test(p); //testメソッドの呼び出し
・・・  //他の処理等
printf( %s, p ); //出力

void test(char *p){
p = "ABC"; // 確保
}

とした時、void test(char*) は結果的に何もしていません。char *p = "ABC"; としていますが、変数 p は引数ですので、この関数から戻った時には、呼び出した方に何も影響を及ぼしません。ですからこのプログラムは正しく動きません。

char *p; //定義
p = test(); //testメソッドの呼び出し
・・・  //他の処理等
printf( "%s?n", p ); //出力

char *test(void){
char *p = "ABC";
return( p );
}

とでもすべきでしょう。あるいは、ちょっと複雑になりますが、以下のようにすべきでしょう。

char *p; //定義
test(&p); //testメソッドの呼び出し
・・・  //他の処理等
printf( %s, p ); //出力

void test(char **p){
*p = "ABC";
}

とすべきです。
お礼コメント
take_july

お礼率 54% (88/162)

有難うございます。
よくわかりました。

既存のソースは構造体の中の一つにポインタを定義してあり、
構造体を受け渡ししていた為、大丈夫なようでした。
(結果的に複雑な方の処理になっていたみたいです。)

自分が例題であげたソースのは空のポインタ(null)を渡してますね。。。
勉強になりました。
投稿日時:2007/12/04 14:35

その他の回答 (全4件)

  • 回答No.5

ベストアンサー率 38% (96/252)

>確保されるとするとこの段階で確保されると思うのですが、
文字列リテラルはコンパイル時の翻訳フェーズで、
実行文字集合に纏められ、実行時には静的記憶域期間を持ちます。
つまり、文字列リテラルはstaticをつけて宣言された変数と
同じ期間存在することになります。
静的記憶域期間とはプログラムの実行全体となっています。
つまり、プログラムの開始時確保され、終了時に解放されます。
お礼コメント
take_july

お礼率 54% (88/162)

>静的記憶域期間とはプログラムの実行全体となっています。
なるほど、勉強になります。

みなさん素早い回答有難うございました。
投稿日時:2007/12/04 13:46
  • 回答No.3

ベストアンサー率 44% (706/1571)

ANo.1の補足について。

"ABC"のような記述に対してはコンパイラはコード領域あるいは静的データ領域に領域を確保しています。これはプログラムの開始から終了まで確保されたままです。
char *p;
p = "ABC";
は、このあらかじめ確保された領域の先頭アドレスをポインタ変数pに代入しているだけです。
したがって
p[0] = 'a';
のように書き換えてはいけません。仕様上は何が起きるか分かりません。

ちなみに
char str[] = "ABC";
は"ABC"が入る大きさ4の文字配列strを確保して"ABC"の内容をコピーしています。
char str[4];
strncpy(str,"ABC",4);
と実質的に同じです。
この場合は
str[0] = 'a';
のように書き換えてもかまいません。
お礼コメント
take_july

お礼率 54% (88/162)

>"ABC"のような記述に対してはコンパイラはコード領域あるいは静的デ
>ータ領域に領域を確保しています。これはプログラムの開始から終了
>まで確保されたままです。

これが知りたかったみたいです。
有難うございました。
投稿日時:2007/12/04 14:36
  • 回答No.2

ベストアンサー率 44% (706/1571)

する必要があるなしではなく、開放してはいけません。
freeで開放できるのはmalloc(or realloc)で確保したメモリだけです。
それ以外のものを参照するポインタ(NULLを除く)でfreeを呼び出した場合は何が起きるか分かりません。
  • 回答No.1

ベストアンサー率 26% (58/222)

結論から言うと無いです。
このような記述をした場合、始めからこれだけのメモリ(4バイト)を含めたコードをコンパイラが生成しますから、プログラム終了時に自動的に介抱されます。
補足コメント
take_july

お礼率 54% (88/162)

ご回答有難うございます。
開放する必要が無いこと分かりました。

まだちょっと分かっていない所があり、
宜しければ教えてください。

char *p;
とした場合、この時点ではポインタを定義しているだけですので、
領域はまだ確保されていないと思います。

p = "ABC";
確保されるとするとこの段階で確保されると思うのですが、
次のように定義した箇所と確保した箇所が違う場合、どこで
開放されるのでしょうか。

char *p; //定義
test(p); //testメソッドの呼び出し
・・・  //他の処理等
printf( %s, p ); //出力

void test(char *p){
p = "ABC"; // 確保
}

このように処理を書くと、printfした時点で、"ABC"の領域は確保されているのでしょうか。
それともtestメソッドが終わった時点でスタック領域のように開放されて、使えない場合があるのでしょうか。

既存のソースにこのような記述があるもので。問題なく動いてはいるのですが、気になってしまって。
宜しくお願いします。
投稿日時:2007/12/04 12:18
結果を報告する
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。
AIエージェント「あい」

こんにちは。AIエージェントの「あい」です。
あなたの悩みに、OKWAVE 3,600万件のQ&Aを分析して最適な回答をご提案します。

関連するQ&A

その他の関連するQ&Aをキーワードで探す

ピックアップ

ページ先頭へ