8

これは私がオンラインで見つけた小さな図書館からのものです:

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はゴミが入っていました。std::ostringstream次に、関数から取得したC文字列は、スタックに割り当てられているため、関数が戻るときに破棄されることに気付きました。だから私は追加しました:

return strdup( out.str().c_str());

これで、関数から必要なテキストを取得できます。

2つの質問があります:

  1. 私はこれを正しく理解していますか?

  2. out後で、 (タイプのstd::ostringstream)静的ストレージが割り当てられていることに気付きました。それは、プログラムが終了するまでオブジェクトがメモリにとどまることになっているという意味ではありませんか?もしそうなら、なぜ文字列にアクセスできないのですか?

4

4 に答える 4

11

strdupは、文字列のコピーをヒープに割り当てます。これは、後で手動で解放する必要があります(free()私が思うに)。オプションがある場合は、を返す方がはるかに良いでしょうstd::string

関数が終了すると破棄される一時的なを返すため、の静的ストレージはout役に立ちません。.str()std::string

于 2010-04-17T04:06:06.960 に答える
3

そうです、それoutはデータセグメントに割り当てられた静的変数です。ただしout.str()、これは一時的にスタックに割り当てられます。したがって、これを行うreturn out.str().c_str()と、スタック一時の内部データへのポインタが返されます。文字列がスタック変数でなくても、c_str「文字列オブジェクトの非定数メンバー関数への次の呼び出しまで変更されないままでいることが許可される」ことに注意してください。

文字列を返すだけではいけないと仮定すると、合理的な回避策を見つけたと思います。

于 2010-04-17T04:12:54.470 に答える
0

strdup()は、ヒープ上のメモリを指しているchar*ポインタを返します。使い終わったらfree()する必要がありますが、そうです。

この場合、静的ローカル変数std::ostringstream outは意味がありません。ただし、返されるstd :: stringも静的であり、観察結果が正しくないことが示されている場合を除きます。

于 2010-04-17T04:12:38.100 に答える
-1

ではGetHandStateBrief、変数outは静的である必要はありません。static string次の元の呼び出しで作成されていた一時的なものを置き換える明示的なものが必要ですout.str()

static std::string outStr;
std::ostringstream out;
... rest of function ...
outStr = out.str();
return outStr.c_str();
于 2010-04-17T04:08:15.520 に答える