First of all, I think this goes under the implementation details umbrella.
I tried that with VS2013.
After you call erase()
, the string pointer returned by c_str()
is not changed because I think the internal string implementation just updates the end of string (changing some internal data member), instead of doing a new heap reallocation for the internal string buffer (such an operation would likely return a new pointer value).
This is a behavior that I noted both for your local s
string and the global st
string.
Note that the STL implementation that comes with VS2013 doesn't use COW (COW seems to be non-standard C++11 compliant), so when you copy the strings with st = s
, you are doing a deep copy, so the two strings are completely independent and they point to different memory buffers storing their respective string contents. So, when you erase something from one string, this operation is in no way reflected to the other copied string.
Sample Code
#include <iostream>
#include <string>
using namespace std;
// Helper function to print string's c_str() pointer using cout
inline const void * StringPtr(const string& str)
{
// We need a const void* to make cout print a pointer value;
// since const char* is interpreted as string.
//
// See for example:
// How to simulate printf's %p format when using std::cout?
// http://stackoverflow.com/q/5657123/1629821
//
return static_cast<const void *>(str.c_str());
}
string st;
void f() {
string s{"Hello world!!!"};
cout << "s.c_str() = " << StringPtr(s) << '\n';
st = s;
s.erase(6);
cout << s << '\n';
cout << "s.c_str() = " << StringPtr(s)
<< "; st.c_str() = " << StringPtr(st) << '\n';
}
int main() {
f();
cout << st << endl;
st.erase(6);
cout << "st.c_str() = " << StringPtr(st) << '\n';
}
Output
C:\Temp\CppTests>cl /EHsc /W4 /nologo test.cpp
test.cpp
C:\Temp\CppTests>test.exe
s.c_str() = 0036FE18
Hello
s.c_str() = 0036FE18; st.c_str() = 01009A40
Hello world!!!
st.c_str() = 01009A40