C++ 从函数返回“c_str”

C++ 从函数返回“c_str”,c++,c,c-strings,c-str,static-allocation,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::co

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

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;
现在我可以从函数中获取所需的文本

我有两个问题:

我理解正确吗

我后来注意到,类型以外的std::ostringstream被分配了静态存储。这难道不意味着在程序终止之前,对象应该留在内存中吗?如果是这样,那么为什么不能访问字符串


strdup在堆上分配字符串的一个副本,我想稍后您必须使用free手动释放该副本。如果您有这个选项,那么最好返回std::string

out的静态存储没有帮助,因为.str返回一个临时std::string,当函数退出时该字符串将被销毁。

在GetHandStateBrief中,变量out不需要是静态的。您需要一个显式静态字符串来替换在原始out.str调用中创建的临时字符串:


strdup返回指向堆上内存的char*指针。你需要在完成后释放它,但是是的,这会起作用

在这种情况下,静态局部变量std::ostringstream out毫无意义,除非返回的std::string也是静态的,而您的观察结果表明它不是真的。

您说得对,out是在数据段上分配的静态变量。但是out.str是在堆栈上临时分配的。因此,当您返回out.str.c_str时,您将返回指向临时堆栈内部数据的指针。请注意,即使字符串不是堆栈变量,c_str也只能在下次调用string对象的非常量成员函数之前保持不变


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

Hmm,在堆上分配了静态变量-从未听说过这样的事情:嗯,字符串的字符数据确实与任何std::string一起存储在堆上,无论是静态的还是其他的。它是存储在数据段上的字符串描述符,就像其他具有全局生存期的变量一样。这是有风险的。在后续调用GetHandStateBrief后,返回的char*不保证有效。如果为True,则每次调用GetHandStateBrief都将使前一次调用返回的指针无效。但是风险是上下文相关的。我也没有投票权,但是函数中的“静态变量,这样我们可以返回一个指针而不是仅仅返回对象”是C++中一个众所周知的反模式。参见Scott Meyer的有效C++第二版,第23条。我不认为这不是更坏的原始代码,除了这一个工作。在C++程序中的扩展并不一定更好。所有的都是真的-但是我会把它放在他试图做的事情上。当CRT不共享时,我不得不在DLL中使用类似的反模式。OTOH,我同意如果可以返回对象,则不应执行此操作。
return strdup( out.str().c_str());
static std::string outStr;
std::ostringstream out;
... rest of function ...
outStr = out.str();
return outStr.c_str();