从函数返回’c_str’

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

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 )分配了静态存储。 这是不是意味着在程序终止之前该对象应该留在内存中? 如果是这样,那为什么不能访问该字符串?

strdup在堆上分配一个字符串的副本,你必须稍后手动free()我认为是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 string

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