c_str()和data():生成一个const char*指针,指向一个临时数组。
有解释说c_str必然带‘\0’,至于data要不要带’\0’,这个标准没说。
string str = "012345";
cout<<"string.data() addr is ";
printf("%p\n",str.data()); //地址相同
cout<<"string.c_str() addr is ";
printf("%p\n\n",str.c_str()); //地址相同
cout<<"test the 0 in string.data() ";
printf("%x\n",*(str.data()+6)); //输出0
cout<<"test the 0 in in string.c_str() ";
printf("%x\n",*(str.c_str()+6)); //输出0
关于c_str()返回的字符串指针指向的数组
引用这里 的解释:这个数组的数据是临时的,当有一个改变这些数据的成员函数被调用后,其中的数据就会失效。因此要么现用先转换,要么把它的数据复制到用户自己可以管理的内存中。
const char* c;
string s="1234";
c = s.c_str();
cout<<c<<endl; //输出:1234
s="abcd";
cout<<c<<endl; //输出:abcd
//补充两个
s="ab"; //输出ab 对于比原来临时数组小的都会直接在原来临时数组上直接修改
printf("%c\n",c[3]); //输出d,也就是说ab字符串只是把临时数组覆盖了,在c[2]的位置置0
s="abcde"; //输出ab,新开辟了内存,并且原来的p依然可以用
s="a"; //输出ab,此时是在新开辟的内存上进行写,所以指针p所指的依然存在
隐患:指针p很不稳定,所以在使用的时候最好copy在自己的内存中使用,strncpy和memcpy都可以。
这个隐患也可以参考这里的关于string类的c_str方法不当的使用方法
勿通过string::data、string::c_str返回指针修改string内容
这里中有提到,勿通过string::data、string::c_str返回指针修改string内容
也就是说data()和c_str()只供引用使用。而且一旦string内容变动,则必须重新获取该指针。string对象的赋值,必须使用符合string类规则的处理方式,比如构造、append、erase等函数进行。
char *p = (char*)str.c_str();
p[0]='p';
cout<<"use point c_str() to change the str ";
cout<<str<<endl; //此时s[0]已经被改变了
所以返回值是const char *,虽然通过强制转换可以修改,但是出于保护不建议这么做
参考
http://book.51cto.com/art/201311/419423.htm
http://blog.csdn.net/zhangwu416826/article/details/7826048
http://www.cnblogs.com/ziwuge/archive/2011/08/30/2159878.html
http://www.metsky.com/archives/582.html
http://www.cnblogs.com/qlwy/archive/2012/03/25/2416937.html