Reputation: 71
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;
}
Upvotes: 0
Views: 631
Reputation: 612934
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;
}
Upvotes: 1
Reputation: 23058
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;
}
Upvotes: 6
Reputation: 5714
return s.c_str();
: you return pointer obtained from temporary variable s
.
You may fix your problem in two ways -
append
.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; }
Upvotes: 0
Reputation: 206577
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.
Upvotes: 0
Reputation: 234685
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
.
Upvotes: 4