c++ - stringstream、string 和 char* 转换混淆

标签 c++ string memory stringstream

我的问题可以归结为,从 stringstream.str().c_str() 返回的字符串在哪里存在内存中,为什么不能将它分配给 const char*?

这个代码示例将比我解释得更好

#include <string>
#include <sstream>
#include <iostream>

using namespace std;

int main()
{
    stringstream ss("this is a string\n");

    string str(ss.str());

    const char* cstr1 = str.c_str();

    const char* cstr2 = ss.str().c_str();

    cout << cstr1   // Prints correctly
        << cstr2;   // ERROR, prints out garbage

    system("PAUSE");

    return 0;
}

stringstream.str().c_str() 可以分配给 const char* 的假设导致了我花了一段时间才找到的错误。

对于奖励积分,谁能解释为什么用

替换 cout 语句
cout << cstr            // Prints correctly
    << ss.str().c_str() // Prints correctly
    << cstr2;           // Prints correctly (???)

正确打印字符串?

我在 Visual Studio 2008 中编译。

最佳答案

stringstream.str() 返回一个临时字符串对象,该对象在完整表达式的末尾被销毁。如果您从该 (stringstream.str().c_str()) 获得指向 C 字符串的指针,它将指向语句结束处被删除的字符串。这就是您的代码打印垃圾的原因。

您可以将该临时字符串对象复制到其他字符串对象并从中获取 C 字符串:

const std::string tmp = stringstream.str();
const char* cstr = tmp.c_str();

请注意,我创建了临时字符串 const,因为对它的任何更改都可能导致它重新分配,从而使 cstr 无效。因此,完全不存储对 str() 的调用结果并仅在完整表达式结束之前使用 cstr 会更安全:

use_c_str( stringstream.str().c_str() );

当然,后者可能并不容易,而且复制成本可能太高。您可以做的是将临时绑定(bind)到 const 引用。这会将其生命周期延长到引用的生命周期:

{
  const std::string& tmp = stringstream.str();   
  const char* cstr = tmp.c_str();
}

IMO 这是最好的解决方案。不幸的是,它不是很为人所知。

关于c++ - stringstream、string 和 char* 转换混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1374468/

相关文章:

android - Delphi - 如何初始化字符串的 TArray?

javascript - 在 JavaScript 中对字符串调用 forEach

.net - 为什么堆栈的深度使用会导致简单解释器的超线性时间行为?

c - 结构体数组占用内存过多

c++ - 将 Xcode 项目与 MathGL 链接时的语义问题

java - 在 openframeworks 中使用 android UI 修改 C++ 程序中的变量?

c++ - 字符串数组输出

memory - ocaml下检测内存是否不足

c++ - 清除 multi_index_container

c++ - 尝试编译并收到以下错误,未定义对某些类的引用。