2017-01-17 12 views
1

What is the difference between char s[] and char *s?Cでエラーが返される理由

私は与えられたリンクに基づいて2つのコードの例を挙げました。 getstring()関数を仮定します。両方として


char *str = "GfG"; /* "GfG" is stored in read only part of shared segment */ 
/* str has auto storage duration,so stored on the stack 
/* No problem: remains at address str after getString() returns*/ 
return str; 

AND

char str[] = "GfG"; /* "GfG" is stored in read only part of shared segment */ 
/* str has auto storage duration,so stored on the stack. 
/* Problem: string may not be present after getSting() returns */ 
return str; 

自動保管期間及びスタック・セグメントに格納された両方の変数を有しています。

次に、なぜ最初の1のためではなく秒1のために働く戻りSTR?

+3

最初はstatic lifetimeの文字列リテラルへのポインタを返します。これは 'getString()'のスコープが残っていると破壊されません。しかし、第二に、 '' GfG ''は実際に文字列リテラルではなく、静的な生存期間を持たないので、生存期間は割り当てられた範囲に縛られます。このようにして、2番目に返されたポインタは無効となり、それを読み取ろうとすると未定義の動作が呼び出されます。 – George

+0

'str []'を 'static char'と定義すると、関数を終了するときに破棄されません。 –

+0

これを確認してくださいhttp://stackoverflow.com/questions/9970295/life-time-of-string-literal-in-c – Karthick

答えて

4

strの両方のバージョンには、自動保存期間があります。しかし、彼らのタイプは異なっており、それはすべての違いをもたらします。

char *str - はポインタです。文字列リテラルを指しています。リテラルの格納時間は静的です。戻り値strは、リテラルのアドレスを返します(strの内容が返されます)。すべて正常です。

char str[] - はローカルアレイです。リテラルから初期化されます。しかし、バッファ全体の持続時間は自動的です。それを返すと、それはポインタに減衰します(アドレスstrが返されます)。バッファはスコープの外に出るので、そのアドレスはぶら下がりポインタになります。

2

文字列リテラルはプログラム実行全体のライフタイムを持ちますが、スコープから外れることはありません。したがって、それらへのポインタは常に動作します。

注意したように、2番目の例の配列は自動記憶域を持ち、関数が返ったときに範囲外になります。返すポインタは無効です。


そして、あなたの配列の例では、コメントに関する小さな注:

char str[] = "GfG"; /* "GfG" is stored in read only part of shared segment */ 

上記のコメントは間違っです。コンパイラが自動的に配列を設定するような配列を初期化すると、この場合文字列リテラルはありません。上記配列の

の定義と初期化がコメントが悪いため、コピー&ペーストのポインタ例として、配列例えば同じである

char str[4] = { 'G', 'f', 'G', '\0' }; 

I 希望に相当しているのですか?最初のコードで

+0

配列の初期化に関連する文字列リテラルが_might_になります。 C11 6.7.9/14: '文字型の配列は、文字列リテラルまたはUTF-8文字列リテラルで初期化することができ、オプションで中括弧で囲みます。 clangの例:https://godbolt.org/g/j6Q052 –

2

char *str = "GfG"; 

ように宣言された変数strが実際に機能を終了した後生存しないであろう自動記憶域期間を持つ関数のローカル変数であるスニペット。

しかし、変数が指す文字列リテラル自体は、静的な記憶期間を持ち、その寿命は関数呼び出しに依存しません。関数を終了した後には生き残ります。関数は文字列リテラルの最初の文字へのポインタを返します。第2のケースで

はローカル配列リテラル文字列の文字によって初期化される

char str[] = "GfG"; 

が宣言されます。関数を終了すると、それはもはや生きていません。したがって、配列の最初の文字へのポインタは無効になります。

static char str[] = "GfG"; 

ようにそれを宣言するために、この場合、関数はの最初の文字へのポインタを返すことがあればあなたが最初のコードスニペットで文字列リテラルのように文字配列と同じ効果を得ることができその静的記憶期間のために機能を終了した後に生きているからである。

関連する問題