2

VC ++では、にconst char*返された値を型キャストしてキャストされた値を出力std::string::c_str()するchar*と、画面に何も出力されません。これがコードスニペットです

#include "stdafx.h"
#include <string>

using namespace std;

string test() { return(string("HELLO"));}


int _tmain(int argc, _TCHAR* argv[])
{
  char* val;
  val = (char*) test().c_str();
  printf("\n %s\n", val);
  return 0;
}

ASCII値val[0]が0であることを確認するだけです。しかし、G ++では、テキストHELLOが表示されます。

const char*からchar*へのキャストは、結果が定義されていない非標準のキャストですか?

4

3 に答える 3

7

文字列を変更した後に値を変更したり、値から読み取ったりしない限り、キャストは問題ありません(ただし、少なくとも警告が表示されるはずです)。

問題は、一時的に関数を呼び出すことです(一時はによってstring返されcat()ます)。の後、;一時はスコープ外になり、一時的にval管理されているメモリを指します。それからUBを読んでいます。

于 2012-08-30T21:11:17.710 に答える
3

によって返された一時的なものtest()がすぐに破棄されるため、未定義の動作が発生します。キャストはそれとは何の関係もありませんでした。

この問題を解決するには、によって返される値test()をローカル変数に割り当てます。これで、への呼び出しを通じて存在し続けますprintf

int _tmain(int argc, _TCHAR* argv[])
{
  string temp;
  char* val;
  temp = test();
  val = (char*) temp.c_str();
  printf("\n %s\n", val);
  return 0;
}
于 2012-08-30T21:10:56.053 に答える
0

キャストなしでも同様の動作が得られることに注意してください(タイプをvalに変更char const*):

char const* val;
val =  test().c_str();
printf("\n %s\n", val);

他の回答で述べたように、この特定の例の問題はキャストではなく、によって返されるポインタが指すデータの存続期間ですc_str()。そのデータは、取得したオブジェクトが死ぬと無効になります(この場合、関数によって返される一時オブジェクトであるため、行末のセミコロンにありtest()ます)。

chrisがコメントで指摘しているように、ポインタがc_str()長寿命のオブジェクトの呼び出しから取得された場合でも、他の理由でデータが無効になる可能性があることに注意してください(基本的に文字列オブジェクトが変更された場合)。

于 2012-08-30T21:23:53.540 に答える