从函数返回'c_str'

时间:2010-04-17 04:03:19

标签: c++ c c-strings c-str static-allocation

这是我在网上找到的一个小型图书馆:

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());

现在我可以从函数中获取我需要的文本。

我有两个问题:

  1. 我是否正确理解了这一点?

  2. 我后来注意到out(类型std::ostringstream)已分配静态存储。这是不是意味着在程序终止之前该对象应该留在内存中?如果是这样,为什么不能访问该字符串?

4 个答案:

答案 0 :(得分:11)

strdup在堆上分配字符串的副本,您必须稍后手动释放(我认为free())。如果您有选择权,那么返回std::string会更好。

out的静态存储无济于事,因为.str()会返回一个临时的std::string,当函数退出时会被销毁。

答案 1 :(得分:3)

你是对的out是在数据段上分配的静态变量。但是out.str()是临时分配在堆栈上的。因此,当您执行return out.str().c_str()时,您将返回指向堆栈临时内部数据的指针。请注意,即使字符串不是堆栈变量,c_str也是“只允许保持不变,直到下一次调用字符串对象的非常量成员函数。”

我认为你已经找到了合理的解决方法,假设你不能只返回一个字符串。

答案 2 :(得分:0)

strdup()返回一个指向堆内存的char *指针。

,当你完成它时,你需要释放()它,但是,这是可行的。

静态局部变量std::ostringstream out在这种情况下没有意义,除非返回的std :: string也是静态的,你的观察结果显示不是真的。

答案 3 :(得分:-1)

GetHandStateBrief中,变量out不需要是静态的。您需要一个明确的static string来替换原始调用中创建的临时out.str()

static std::string outStr;
std::ostringstream out;
... rest of function ...
outStr = out.str();
return outStr.c_str();