3

GetTypeName は std::string で、次のコード

printf("%#x\n", proto->GetTypeName().c_str());
printf("%s\n", proto->GetTypeName().c_str());
const char *res = proto->GetTypeName().c_str();
printf("%#x\n",res);
printf("%s\n",res);

次の出力が生成されます。

0x90ef78
ValidTypeName
0x90ef78
ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■ю■←ЬЬQщZ

アドレスは常に同じです。次のコード(行は交換です)

const char *res = proto->GetTypeName().c_str();
printf("%#x\n",res);
printf("%s\n",res);
printf("%#x\n", proto->GetTypeName().c_str());
printf("%s\n", proto->GetTypeName().c_str());

この出力を生成すると、アドレスは常に異なります。

0x57ef78
  Y
0x580850
ValidTypeName

私は何を間違っていますか?

strlen(res)

無効なサイズを返すため、strcpy もできません。

4

1 に答える 1

5

YourGetTypeName 関数は std::string を返し、c_str を呼び出してその文字列の内部データへのポインターを取得しています。

これは一時的なものであるため、返される std::string はステートメントの最後で削除されます

const char *res = proto->GetTypeName().c_str();

ただし、削除されたデータを指している res がまだあります。

編集:コードを次のように変更します:-

const std::string& res = proto->GetTypeName(); 

そして、次のように printf のその文字列で .c_str() を呼び出します:-

printf("%#x\n",res.c_str());
printf("%s\n",res.c_str());

参照に一時を割り当てると、その一時の有効期間が参照の有効期間と同じになるように延長されます...

さらに良いことに、印刷には std::string と iostream を使用し、不要な場合は低レベルのポインターをいじるのをやめてください:)

于 2012-10-31T13:24:04.523 に答える