Getting error with const char

I am trying to implement the functions below, but the output for foo() is a bunch of nonsense. I tried to run the debugger and didn't see any problems inside the append function. But the total variable in foo() isn't properly assigned the value "abcdef". Any ideas why?

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;
}

Answers


Because in append(), you returned s.c_str(); then, s is destructed, which means that the pointer returned is invalidated immediately.

Let append() return std::string to solve this issue.

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;
}

Undefined Behaviour. c_str is only valid for the lifetime of s (and only then if s is not modified in any way). Once append has returned, s is out of scope. Boom!

One fix is to have append return a std::string.


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

The variable s is local to the function. It is destroyed when the function returns. That means that the value that you return, s.c_str(), points to memory that has been deallocated. De-referencing that memory results in undefined behaviour.

The rule with c_str() is, loosely put, that the value it returns is guaranteed to be valid until either the string object is modified or destroyed.

Simply put, you should stop using C strings unless you need to use them for interop. Your function should be:

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

You are returning a pointer from append() that is not valid when the function returns.

string s(s1);

defines a object in append(). It is destroyed when you return from the function. Hence, the returned value of s.c_str() is not valid in foo.

You can change your code to be:

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

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

That should work.


return s.c_str(); : you return pointer obtained from temporary variable s.

You may fix your problem in two ways -

  1. Return std::string by value from append.
  2. Pass to append pointer to fill it with data -
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;
}

Need Your Help

Google/Analytics.h file not found when adding to AppDelegate

ios objective-c google-analytics cocoapods

I am trying to integrate Google Analytics in my ios project using Cocoapods. However, after following this for the steps till adding configuration file to my project, when importing the Google/Anal...

Using a NSSavePanel from Qt for a native save dialog

macos qt5 objective-c++

The code below works most of the time, maybe a more experienced Objective C++ programmer can help me: