1

私は今日、Windows マシンでは特定の文字列がかなり文字化けするが、Mac ではそうではない、プラットフォーム固有のバグに対処していました。std::stringこのバグは、 と の間で明示的および暗黙的な変換を行ういくつかの行に関係していましたconst char *。基本的に、署名付きの関数がありました

void foo(const std::string &id);

foo はある時点で文字列を出力します。Windows では、以下のように呼び出されると、さまざまなレベルの破損 (最初の数文字または文字列全体が文字化けする) で id 文字列が出力されます。

std::string mystring = bar();
const char *id = mystring.c_str();
foo(id); // pass the C style string in because I thought that's what it took

正しく呼び出すことでエラーを修正しましたfoo

std::string mystring = bar();
foo(mystring);

私はいくつかのことを理解することはできませんが、

  • バグの原因は何ですか?
  • なぜプラットフォーム固有だったのですか?
  • const char *と の間の暗黙的な変換はstd::string安全ですか?
4

3 に答える 3

4

私は大雑把な推測をして、あなたの質問のコードはあなたの実際のコードを代表していないと言います。fooこの症状は、メモリが再利用されているように聞こえます。これは、呼び出し時に文字列が無効になっていることを意味します。c_strたとえば、一時的に使用することでそれを取得できますconst char *id = bar().c_str();

于 2013-07-18T22:25:30.210 に答える
2

考えられる可能性は 2 つありますが、あなたが言ったことだけでは、どちらかわかりません。

  1. foo一時への参照を取得するケースを誤って処理します。たとえば、おそらくそのパラメーターへのポインターをどこかに隠しておき、他のコードがfoo戻り後にそれを使用します。

  2. のデータにmystringはゼロバイトが埋め込まれており、 を呼び出すと長さが失われますc_str

于 2013-07-18T21:48:44.457 に答える
0

何が起こっているのかわかりませんが、 c_str() の結果をあなたが所有するバッファにコピーし、それに foo() を呼び出し、作成したバッファを破棄しない理由はありますか? それでも解決しない場合は、実装ではなく foo() のみの問題か、実装と foo() の間の競合です。

于 2013-07-18T22:14:38.633 に答える