2

次のコードがある場合:

{
    UnicodeString sFish = L"FISH";
    char *szFish = AnsiString(sFish).c_str();

    CallFunc(szFish);
}

AnsiString次に、作成される一時的なスコープはどのくらいでszFish、有効なデータをどのくらいの期間指し示していますか?機能に対しては引き続き有効ですCallFuncか?

スコープは1行だけ続くのでしょうか、それともブロック全体で続くのでしょうか。

4

4 に答える 4

5

szFishは、を呼び出す前は無効です。これは、がすぐに破棄され、削除されたばかりの内部バッファを指している一時オブジェクトであるCallFunc()ためです。AnsiStringszFish

AnsiStringインスタンスがの呼び出しに対して有効であることを確認してくださいCallFunc()。例えば:

CallFunc(AnsiString(sFish).c_str());
于 2012-11-20T13:42:52.833 に答える
4

私は交換します:

char *szFish = AnsiString(sFish).c_str();

と:

AnsiString as(sFish);
char *szFish = as.c_str();

AnsiStringクラスはわかりませんが、コードでは、を呼び出す前にそのデストラクタがCallFunc()起動し、おそらく、で指定した文字列を解放します*szFish。一時オブジェクトをスタック上の「名前付き」オブジェクトに置き換えると、その存続期間は、それが定義されているブロックの終わりまで延長されます。

于 2012-11-20T13:43:08.270 に答える
2

C++11標準の$12.2.3は次のように述べています。

実装が重要なコンストラクター(12.1、12.8)を持つクラスの一時オブジェクトを導入する場合、その一時オブジェクトに対してコンストラクターが呼び出されるようにする必要があります。同様に、デストラクタは、重要なデストラクタ(12.4)を使用して一時的に呼び出されるものとします。一時オブジェクトは、それらが作成されたポイントを(字句的に)含む完全式(1.9)を評価する最後のステップとして破棄されます。これは、その評価が例外のスローで終了した場合でも当てはまります。一時オブジェクトを破棄することによる値の計算と副作用は、特定の部分式ではなく、完全な式にのみ関連付けられます。

(強調鉱山)

これには追加の注意事項がありますが、この状況には適用されません。あなたの場合、完全な式はこのステートメントの示された部分です:

char *szFish = AnsiString(sFish).c_str();
//             ^^^^^^^^^^^^^^^^^^^^^^^^^

したがって、インスタントszFishが割り当てられ、一時オブジェクト(つまりAnsiString(sFish))のデストラクタが呼び出され、その内部メモリ表現(がc_str()指す場所)が解放されます。したがって、szFishすぐにダングリングポインタになり、アクセスは失敗します。

あなたは言うことによってこれを回避することができます

CallFunc(AnsiString(sFish).c_str());

代わりに、ここにあるように、一時的なものは完全な式の後で(つまり、すぐに;)破棄さCallFuncれ、生の文字列を読み取ることができます。

于 2012-11-20T13:55:10.653 に答える
1

この場合の範囲は、AnsiString「呼び出しの直前から直後c_str()まで」です。

このように考えると役立つ場合があります。

char *szFish; 

{ 
    AnsiString tmpString(sFish); 
    szFish = tmpString.c_str(); 
}
于 2012-11-20T13:47:16.873 に答える