2017-02-02 10 views
1

私はこれが安全であることを理解...functionからstring literalを割り当てられたconst char *を返すのは安全ですか?これは

const char *get_str_literal() { 
    return "I literally can't even"; 
} 

しかし、ありますか?

const char *get_str_literal() { 
    const char *str = "I literally can't even"; 
    return str; 
} 

そうでない場合、なぜですか?

を編集します。上記の2番目のコードスニペットとの違いは次のとおりです。

const char *get_str_literal() { 
    const char str[] = "I literally can't even"; 
    return str; 
} 

文字列リテラルの内容が自動配列記憶域にコピーされますか?何が起こるのですか? 2番目の例で

+2

これらは同じですが、コンパイラはおそらく同じコードを生成します –

+3

これらはどちらも問題ありません。あなたが比較しなければならないものは 'const char str [] ="私は文字通りにはできません ";' –

+0

@DavidBowlingこれは実際に私が約質問していたものでした。私は配列とポインタがしばしば振る舞いで重なっていることを理解していますが、これは配列(つまり 'const char str []')をポインタに代入すると問題が生じる状況でしょうか?アレイの割り当ては自動ストレージですか? – kylemart

答えて

3

const char *get_str_literal() { 
    const char *str = "I literally can't even"; 
    return str; 
} 

strは静的記憶域期間を持つリテラル文字列を指すように設定ポインタです。したがって、呼び出し元関数で実行が再開されると、返されるポインタは何か、つまり文字列リテラルを指し示します。

はあなたの最後の例では:

const char *get_str_literal() { 
    const char str[] = "I literally can't even"; 
    return str; 
} 

文字配列str[]は文字列リテラルでを初期化されます。初期化後、str[]'\0'ターミネータまでの文字列リテラルの文字を含むcharの配列です。 がreturnステートメントで検出されると、それはconst charへのポインターに変換され、呼び出し関数に返されます。しかし、str[]には自動保存期間があるため、寿命が終了してポインタが不確定になり、未定義の動作につながります。

+0

ローカル(自動)変数がスタックに割り当てられていることを追加したいと思います。したがって、最初のスニペットでは、それが指しているデータではなく、ローカル_ポインタが消えます。 2番目のスニペットでは、文字列自体が消えます。 – linuxfan

+0

@ linuxfan--(1/2)はい。関数がポインタを返すと言うと、関数がポインタの_value_を返すことを意味します。最初のケースでは、ローカルポインターの有効期間は終了しますが、その値は呼び出し元に渡されます。文字列リテラルは静的持続時間を持つので、この値は呼び出し側のポインタに有効に割り当てることができます。 2番目のケースでは、文字列の最初の要素へのポインタの値が呼び出し側に返されます。しかし、文字列の存続期間が終了したため、この値を呼び出し元のポインターに割り当てることはできません。 –

+0

@ linuxfan--(2/2)関数が文字列の最初の要素へのポインタの値を返すと、このポインタも範囲外です。しかし、それが指し示すオブジェクトは範囲外であるため、値そのものは不確定になります(C11§6.2.42)。また、スタックとヒープの概念は広く使われていますが、C標準の一部ではありません。実装の詳細です。私は、この文脈でストレージの期間を使用することを好みます。これは、スタンダードがこれらの問題をどのように記述しているかということです。 –

関連する問題