【问题标题】:Getting error with const char使用 const char 出错
【发布时间】:2014-03-10 15:58:53
【问题描述】:

我正在尝试实现以下功能,但 foo() 的输出是一堆废话。我尝试运行调试器,但在 append 函数中没有发现任何问题。但是 foo() 中的总变量未正确分配值“abcdef”。任何想法为什么?

int main()
{
    cout<<"foo is"<<endl;
    foo();
    return 0;
}

const char* append(const char* s1, const char* s2) {
    string s(s1);
    s += s2;
    return s.c_str();
}

void foo() {
    const char* total = append("abc", "def");
    cout<<total;
}

【问题讨论】:

    标签: c++ string char constants


    【解决方案1】:

    因为在append(),你返回了s.c_str();那么s就被破坏了,也就是说返回的指针立即失效。

    append()返回std::string来解决这个问题。

    std::string append(const char* s1, const char* s2) {
        return std::string(s1).append(s2);
    }
    
    void foo() {
        std::string total = append("abc", "def");
        cout << total;
    }
    

    【讨论】:

    • @ShafikYaghmour 已编辑可能的修复。
    • 静态本地是非常糟糕的建议。
    • 是的......虽然它是代码更改最少的“修复”。
    • 那又怎样?既然可以做好,为什么还要建议做坏事?
    【解决方案2】:

    未定义的行为c_str 仅在 s 的生命周期内有效(并且仅当 s 未以任何方式修改时)。一旦append 返回,s 就超出了范围。 轰隆隆!

    一种解决方法是让append 返回std::string

    【讨论】:

    • +1 for Boom!(当然是正确答案 - 必须添加一些字符才能发表评论)
    【解决方案3】:
    const char* append(const char* s1, const char* s2) {
        string s(s1);
        s += s2;
        return s.c_str();
    }
    

    变量s 是函数的局部变量。它在函数返回时被销毁。这意味着您返回的值s.c_str() 指向已被释放的内存。取消引用该内存会导致未定义的行为。

    c_str() 的规则松散地说,它返回的值保证在字符串对象被修改或销毁之前是有效的。

    简单地说,您应该停止使用 C 字符串,除非您需要将它们用于互操作。你的功能应该是:

    string append(const string& s1, const string& s2)
    {
        return s1 + s2;
    }
    

    【讨论】:

    • 返回对局部变量的引用与返回对局部变量的指针一样危险。
    • @timrau 是的,这是个错误
    【解决方案4】:

    您正在从append() 返回一个在函数返回时无效的指针。

    string s(s1);
    

    append() 中定义一个对象。当您从函数返回时,它会被销毁。因此,s.c_str() 的返回值在foo 中无效。

    您可以将代码更改为:

    string append(const char* s1, const char* s2) {
        string s(s1);
        s += s2;
        return s;
    }
    
    void foo() {
        string total = append("abc", "def");
        cout<<total;
    }
    

    应该可以的。

    【讨论】:

      【解决方案5】:

      return s.c_str(); :返回从临时变量s 获得的指针。

      您可以通过两种方式解决您的问题 -

      1. append 中按值返回std::string。
      2. 传递给append指针以填充数据 -
      void append(const char* s1, const char* s2, char* out) {
        string s(s1);
        s += s2;
        strncpy(out, s.c_str(), s.size()+1);
      }
      
      void foo() {
        char total[7] = {0}; //should be enough to carry appended string + '\0'
        append("abc", "def", total);
        cout<<total;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-23
        • 1970-01-01
        • 1970-01-01
        • 2017-03-29
        • 2011-12-15
        • 2013-11-09
        • 1970-01-01
        • 2013-07-20
        相关资源
        最近更新 更多