「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > std::string 関数から C の文字列リテラルを返すと、機能するように見えることがあるのに、依然として未定義の動作が発生するのはなぜですか?

std::string 関数から C の文字列リテラルを返すと、機能するように見えることがあるのに、依然として未定義の動作が発生するのはなぜですか?

2024 年 11 月 18 日に公開
ブラウズ:746

Why Does Returning a C String Literal from a std::string Function Seem to Work Sometimes, But is Still Undefined Behavior?

std::string 関数から C 文字列リテラルを返し、 c_str()

を呼び出す C では、 std::string 関数から C 文字列リテラルを返すことは、未定義の動作を引き起こす可能性のある不適切な行為。ただし、よくある誤解は、このコードは場合によっては機能するように見えても、失敗するはずだということです。

「それは私です!!」の場合が myFunction() に渡されると、C 文字列リテラルは暗黙的に std::string オブジェクトに変換されます。返された std::string オブジェクトは、文字列リテラルのコピーを含む内部文字バッファーを指します。 std::string で c_str() を呼び出すと、このバッファへのポインタが返されます。

std::string オブジェクトの内部文字バッファが静的メモリに格納されていないために、潜在的な問題が発生します。 myFunction() 関数が戻ると、std::string オブジェクトとその内部バッファーは破棄されます。これは、c_str() から取得したポインタが、割り当て解除されたメモリを指すダングリング ポインタになることを意味します。

ただし、特定の実装および特定の状況では、オペレーティング システムは、割り当て解除された std::string によって使用されるメモリをすぐに再利用できない場合があります。 。これはメモリの永続性として知られています。その結果、オペレーティング システムは、コードが割り当て解除されたメモリにアクセスし続けることを誤って許可し、コードが正しく動作するかのように錯覚させます。

この動作は C では未定義であることを強調することが重要です。言語標準では、この状況で何が起こるかが定義されておらず、実装が異なれば動作も異なる可能性があります。メモリの永続性に依存することは危険であり、さまざまなコンテキストやさまざまなオペレーティング システムで予期しないエラーが発生する可能性があります。

したがって、サンプル コードは場合によっては機能するように見えても、未定義の動作とみなされ、実行する必要があります。避けられた。このような問題を防ぐには、内部バッファへの直接ポインタではなく、 std::string 関数から文字列リテラルのコピーを返すことをお勧めします。

最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3