运行一个简单的程序来测试字符串对象中的指针,得到
0x1875028
Hello
0x1875058 0x1875028
Hello world!!!
0x1875028
我想了解为什么s.c_str()
会在erase()调用之后更改值,而不是st.c_str()
。
以下是简单的代码:
#include <vector>
#include <unordered_map>
#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;
string st;
void dum() {
string s("Hello world!!!");
printf("%p\n", s.c_str());
st = s;
s.erase(6);
cout << s << endl;
printf("%p %p\n", s.c_str(), st.c_str());
}
int main(int argc,char *argv[]) {
dum();
cout << st << endl;
st.erase(6);
printf("%p\n", st.c_str());
return 0;
}
答案 0 :(得分:1)
这实际上取决于您使用的版本。例如,请参阅Is std::string refcounted in GCC 4.x / C++11?。当你写两个string
,a
和b
a = b;
然后有一个问题是它们是否在内部指向同一个对象(直到其中一个被修改)。因此,您的计划展示的任何一种行为都不是很令人惊讶。
答案 1 :(得分:0)
首先,我认为这属于实施细节伞。
我用VS2013试过了。
调用c_str()
后,s
返回的字符串指针不会更改,因为我认为内部字符串实现只是更新字符串的结尾(更改一些内部数据成员),而不是内部字符串缓冲区的新堆重新分配(这样的操作可能会返回一个新的指针值)。
我注意到这是一种针对您的本地st
字符串和全局st = s
字符串的行为。
请注意,VS2013附带的STL实现不使用COW(COW似乎是非标准的C ++ 11兼容),因此当您使用#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';
}
复制字符串时,您正在执行< em> deep copy ,因此这两个字符串是完全独立的,它们指向存储各自字符串内容的不同内存缓冲区。因此,当您从一个字符串中删除某些内容时,此操作绝不会反映到另一个复制的字符串中。
示例代码
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
<强>输出强>
os.system