从函数返回’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());
现在我可以从函数中获取我需要的文本。
我有两个问题:
-
我理解正确吗?
-
后来我注意到
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();