从功能返回“ C_STR”
-
27-09-2019 - |
题
这是我在网上找到的一个小图书馆:
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()
我认为)。如果您有选择权,最好回来 std::string
.
静态存储 out
没有帮助,因为 .str()
返回临时 std::string
, ,当功能退出时被破坏。
其他提示
你是对的 out
是分配在数据段上的静态变量。但 out.str()
是在堆栈上分配的临时性。所以当你这样做 return out.str().c_str()
您正在将指针返回到堆栈临时的内部数据。请注意,即使字符串不是堆栈变量, c_str
“仅被授予保持不变,直到下一个呼叫字符串对象的非恒定成员函数为止。”
我认为您已经击中了合理的解决方法,假设您不能只返回字符串。
strdup()返回一个指向堆上内存的char*指针。完成后,您需要释放()它,但是是的,这将起作用。
静态局部变量 std::ostringstream out
在这种情况下,除非返回std ::字符串也是静态的,否则您的观察结果也不是真的。
在 GetHandStateBrief
, , 多变的 out
不需要静态。您需要明确的 static string
代替原始呼叫中创建的临时性 out.str()
:
static std::string outStr;
std::ostringstream out;
... rest of function ...
outStr = out.str();
return outStr.c_str();