这是我在网上找到的一个小型图书馆:
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());
现在我可以从函数中获取我需要的文本。
我有两个问题:
我是否正确理解了这一点?
我后来注意到out
(类型std::ostringstream
)已分配静态存储。这是不是意味着在程序终止之前该对象应该留在内存中?如果是这样,为什么不能访问该字符串?
答案 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();