【问题标题】:how to set char * value from std string (c_str()) not working如何从std字符串(c_str())设置char *值不起作用
【发布时间】:2011-05-10 08:16:20
【问题描述】:

我不知道,但这对我不起作用,当我尝试从返回 std 字符串的函数中设置 char * 值时,我得到了垃圾值:

string foo()
{
  string tmp ="dummy value";
  return tmp;
}

char* cc = (char *) foo().c_str(); // if i remove the casting im getting error 
// when i print the cc i get garbage 
printf("%s",cc);

【问题讨论】:

    标签: c++ string pointers


    【解决方案1】:

    cc 指向的数据的生命周期与它来自的字符串的生命周期相同(充其量 - 如果您修改字符串,它会更短)。

    在您的情况下,foo() 的返回值是一个临时值,在 cc 的初始化结束时被销毁。

    为避免char *cc = foo().c_str() 中的编译错误,您不应强制转换为char*,您应该切换到const char *cc,因为const char*c_str() 返回的内容。不过,这仍然不能解决主要问题。

    最简单的修复方法是:

    printf("%s", foo().c_str()); // if you don't need the value again later
    
    const string s = foo();
    const char *cc = s.c_str();  // if you really want the pointer - since it's
                                 // in the same scope as s, and s is const,
                                 // the data lives as long as cc's in scope.
    
    string s = foo();
    printf("%s", s.c_str());     // if you don't store the pointer,
                                 // you don't have to worry about it.
    
    std::cout << foo(); // printf isn't bringing much to this party anyway.
    

    【讨论】:

      【解决方案2】:

      foo 的结果是一个临时对象,在char * cc = ... 行的末尾被销毁。将其存储在常量引用中:

      const string& cc = foo();
      printf ("%s", cc.c_str());
      

      【讨论】:

      • 完全正确; const reference 延长右值的寿命恰好是一个奇特的规则,并且“只”记住 value 也可以。 (可能在 C++11 中使用移动语义进行了优化)。
      • 假设移动语义或 RVO 正在开发中,使用值类型几乎是等价的。但是该引用阻止我们依赖编译器优化。
      • @xtofl: 如果值是使用foo() 作为初始化器存储的,则不需要移动语义。无聊的旧 C++03 复制省略就可以了。
      • +1 用于解释代码的问题并为问题提供“更好的世界”解决方案 :-)
      【解决方案3】:

      将内存位置传递给 foo() 并让 foo 修改它:

      void foo (string* _out_newStr)
      {
          _out_newStr->assign("dummy string"); //This is wrong -> _out_newStr = "dummy string";
          return;
      }
      

      然后,当您使用字符串对象的“c_str()”函数时,您将返回一个 const char* 值,正如已经指出的那样。

      【讨论】:

      • @Nawaz 这很有帮助...想扩展吗?我也愿意学习。
      • @Dennis: _out_newStr 是一个指向std::string 的指针,你怎么给它分配字符文字呢?您的代码甚至无法编译。
      • 即使您将其更改为*_out_damned_spot = "dummy string",在 C++ 中使用单个输出参数也是一种尝试性的优化,通常是不必要的。它很可能比依赖 RVO,因为调用者必须创建一个空字符串,然后你分配给它,而通过足够的复制省略,调用者的字符串可以直接从文字构造。只是按价值返回,直到证明不是这样。
      • @Nawaz:你是对的。它没有。向 OP 道歉。由于我工作的年龄,我实际上已经有大约 3 年没有使用过弦乐了。我已经修改了我的帖子。
      • @Dennis:恢复了反对票并立即赞成。顺便说一句,您也可以使用参考:void foo(string &amp; s) { s = "dummy string"; }。现在很好。
      【解决方案4】:

      code-sn-p 调用未定义的行为,因为从调用创建的临时std::string 在表达式末尾被销毁,但指向被销毁对象的cc 即使在此之后仍被使用。

      【讨论】:

        【解决方案5】:

        怎么样:

        printf("%s", foo.c_str() );
        

        或者更好的是,忘记使用字符指针。

        【讨论】:

        • std::cout &lt;&lt; foo() 怎么样。 :D
        猜你喜欢
        • 2011-08-20
        • 2014-02-16
        • 2020-07-08
        • 1970-01-01
        • 2021-01-21
        • 2021-11-02
        • 2020-03-26
        • 1970-01-01
        • 2013-08-31
        相关资源
        最近更新 更多