2 に答える
これは完全に欠陥があります。を呼び出すたびに、一時的な文字列を作成および破棄しますTest()
。Test().c_str()
temporary が破棄された後に返されたポインタを使用してメモリにアクセスしようとしても意味がありません - メモリはすでに解放されています。古い値が含まれている可能性がありますが (アクセス前に何も書き込まれていない場合)、何かが含まれている可能性もあります (アクセス前に再利用された場合)。それは未定義の動作です。
VC++の場合は一度上書きされ、それ以外の場合はありません。GCC を使用すると、上書きされることはありません。しかし、これは純粋なチャンスです。繰り返しますが、UB です。
未定義の動作があります。std::string
によって返されるは一時的なものであり、によって返される( に格納されている)Test()
ポインタは、一時的な有効期間が終了すると無効になります。これは、何でも起こり得ることを意味します。ポインタが指す配列にはガベージが含まれている可能性があります。元の文字列であるか、実装によって先頭が null で終了している可能性があります。これにアクセスすると、セグメンテーション違反が発生するか、元の文字列データにアクセスできる可能性があります。これは、異なるコンパイラや標準ライブラリの実装によって異なる場合があり、通常は異なります。c_str()
j
char *j = const_cast<char*>(Test().c_str());
// The contents pointed to by j are no longer valid and access that content
// is undefined behavior
cout << "address:"<< (unsigned)Test().c_str() << endl;
Test()
呼び出すたびにテンポラリを返すため、アドレスは呼び出しごとに異なります。一部のコンパイラはこれを最適化したり、データの割り当てで同じメモリ ブロックを取得したりすることがありますが、同じであるとは限りません。