関数から「C_STR」を返す
-
27-09-2019 - |
質問
これは私がオンラインで見つけた小さなライブラリからのものです:
const char* GetHandStateBrief(const PostFlopState* state)
{
static std::ostringstream out;
// ... rest of the function ...
return out.str().c_str()
}
私のコードではこれを行っています:
const char *d = GetHandStateBrief(&post);
std::cout<< d << std::endl;
今、最初は d
ごみが含まれています。次に、関数から得ているC文字列が機能したときに破壊されることに気付きました。 std::ostringstream
スタックに割り当てられます。だから私は追加しました:
return strdup( out.str().c_str());
そして今、私は関数から必要なテキストを取得できます。
私には2つの質問があります:
私はこれを正しく理解していますか?
私は後でそれに気づきました
out
(タイプのstd::ostringstream
)静的ストレージで割り当てられました。それは、プログラムが終了するまでオブジェクトがメモリにとどまることになっているという意味ではありませんか?もしそうなら、なぜ文字列にアクセスできないのですか?
解決
strdupはヒープ上の文字列のコピーを割り当てます。これは後で手動で解放する必要があります( free()
おもう)。オプションがある場合は、返す方がはるかに良いでしょう std::string
.
の静的ストレージ out
なぜなら、助けにはならないからです .str()
一時的なものを返します std::string
, 、関数が終了すると破壊されます。
他のヒント
あなたは正しいです out
データセグメントに割り当てられた静的変数です。しかし out.str()
スタックに一時的に割り当てられています。だからあなたがそうするとき return out.str().c_str()
スタックの一時的な内部データへのポインターを返しています。文字列がスタック変数でない場合でも、 c_str
「文字列オブジェクトの非適切なメンバー関数への次の呼び出しまで、変更されないようにすることのみが付与されています。」
文字列を返すことができないと仮定して、合理的な回避策にぶつかったと思います。
strdup()は、ヒープのメモリを指しているchar*ポインターを返します。あなたがそれを完了したときにそれを解放する必要がありますが、はい、それはうまくいくでしょう。
静的ローカル変数 std::ostringstream out
この場合、STD :: Stringが返されない限り、理にかなっていません。また、観察が真実ではないことが示されている静的です。
の GetHandStateBrief
, 、 変数 out
静的である必要はありません。明示的なものが必要です static string
元の電話で作成されていた一時的なものを置き換えるために out.str()
:
static std::string outStr;
std::ostringstream out;
... rest of function ...
outStr = out.str();
return outStr.c_str();