関数内の自動変数(ポインタと配列の違い)

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
テニス

関数内の自動変数(ポインタと配列の違い)

#1

投稿記事 by テニス » 10年前

すみません!先ほど質問した者ですが、肝心なことを聞く前に「解決」をしてしまったため、読んで貰えなかったら
困るのでもう一度トピック建てさせて下さい。

コード:

void charTest(char** str){
    char *p = "charTest";      //これはOK
    //char p[]="charTest";       //これはNG
    
    *str = p;
}

int _tmain(int argc, _TCHAR* argv[])
{
    char* cMoji = "main";

    charTest(&cMoji);
    std::cout << cMoji << "\n";

    return 0;
}
先ほど教えていただいた部分を修正したコードです。

charTest内で、
char*のポインタ型で自動変数を作成すると、main関数での出力は「charTest」と表示されますが、
char型の配列で自動変数を作成すると、main関数での出力は 不定のランダムな文字列 が表示されます。

関数を抜けたら、自動変数はメモリから削除されるので、不定な文字列が表示されるのが
当然かなと思ったのですが、なぜポインタ変数は関数を抜けても残っているのでしょうか?

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 関数内の自動変数(ポインタと配列の違い)

#2

投稿記事 by みけCAT » 10年前

(staticでない)「ポインタ変数」は関数(スコープ)を抜けたら残りません。
「文字列リテラル」はstatic領域に確保される(?)ので残るのだと思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: 関数内の自動変数(ポインタと配列の違い)

#3

投稿記事 by h2so5 » 10年前

"charTest" 自体は静的記憶領域に存在します。
ですから、自動変数pの寿命と関係なくプログラム実行中ずっと有効です。

char *p = "charTest"; の場合はpは "charTest" のアドレスを指しているので関数を抜けても問題ありません。

しかし、char p[] = "charTest"; は配列 p の内容を "charTest" で初期化するという意味です。
pは "charTest" ではなく配列を指していますから、関数を抜けて配列の寿命がなくなると無効なアドレスになってしまいます。

テニス

Re: 関数内の自動変数(ポインタと配列の違い)

#4

投稿記事 by テニス » 10年前

みけCATさんh2so5さんありがとうございます!
ばっちり理解出来ました!

char* p = "charTest"は、静的領域にある文字列リテラルのアドレスを渡しており、関数を抜けても有効で、
char p[] = "charTest"は、関数内で自動変数を初期化しただけなので、関数を抜けたら消滅するんですね。

今日一日だけですごくポインタの理解が深まりました。
ありがたいサイトに感謝です。

閉鎖

“C言語何でも質問掲示板” へ戻る