2011-09-17 15 views
1

私たちは、コードのこの部分を実行すると、それが正常に動作し、画面上string constantを印刷します:この場合、char []とchar *はどう違うのですか?

char *someFun(){ 
    char *temp = "string constant"; 
    return temp; 
} 
int main(){ 
    puts(someFun()); 
} 

しかし、私たちは、次のようなコードを実行すると、それが画面上にいくつかのゴミを仕事と印刷されません。

char *someFun1(){ 
    char temp[ ] = "string"; 
    return temp; 
} 
int main(){ 
    puts(someFun1()); 
} 

理由は何ですか?本質的に、両方の関数は似たようなことをします(つまり、 "文字列"を返す)が、それでもそれらは異なった振る舞いをします。何故ですか?

答えて

5
char *temp = "string constant"; 

string constantリテラルは読み取り専用セグメントにあります。プログラムの終了時に割り当てが解除されます。だから、それを指す参照を持つことができます。

char temp[ ] = "string"; 

stringスタック上に常駐するtempにコピーされます。関数が復帰すると、関数スコープ内の変数の割り当てを解除するスタックの巻き戻しが開始されます。しかし、スタックにもう存在しない参照を返しているので、あなたはゴミを受け取っています。しかし、時には正しい結果が得られるかもしれませんが、それに頼るべきではありません。

+1

引数、戻りアドレスやフレームポインタのような制御情報、 'puts()'のローカル変数は 'someFun1()'のローカル変数(配列)が以前に使った空間を使用している可能性があります。 –

+2

ちなみに、文字列リテラルを扱うときの問題を避けるためには、 'const char *'変数の中にポインタを格納する必要があります。そうすれば、コンパイラはそれらを変更しようとするとあなたをブロックします。 –

3

最初のケースでは、ポインタtempは、"string constant"を格納するグローバル定数を指します。したがって、ポインタを返すときは有効です。

2番目のケースでは、文字列 "'はスタック上の文字配列にすぎません。これは関数から戻った後に終了します。

+0

なぜ最初の場合はグローバルヒープに格納され、2番目の場合はローカルスタックに格納されるのですか? – buch11

+2

デフォルトでは、文字列リテラルはグローバルに格納されます。しかし、あなたがchar []を宣言するときには、 '{'s'、 't'、 'r'、}の短い形式として文字列を入れることが許されています。 'i'、 'n'、 'g'} '。 – Mysticial

+0

...ヌルターミネータを含む。 –

関連する問題