c++ string的c_str() 疑惑

neigedg 2017-08-18 11:21:01
环境:
CentOS release 6.5 (Final)
Linux bogon 2.6.32-431.el6.x86_64
gcc 版本 4.7.4 (GCC)


问题描述:
如果用一个const char *p 指向string ss.c_str()的返回地址,
改变了ss的值之后, *p的值也会相应改变,
but, 9test.cpp的情况下就没改变,求解惑。


备注:
虽然实际上这么干的情况很少,需要用到c_str()的时候都是直接strcpy走了之后再使用,
但这种情况实在不解。


代码1:

9test.cpp:

#include <iostream>
#include <cstring>
using namespace std;

int main()
{
string ss("abcdefghigklmnopq");

const char *tmp = ss.c_str();
cout << "ss.c_str() 1 = " << tmp << endl;
cout << "ss.c_str() 1 , addr = " << static_cast<void*> (const_cast<char *> (tmp)) << endl;

ss = "bacdbefghigkgilfgimnopq";

cout << "ss.c_str() 2 = " << tmp << endl;
cout << "ss.c_str() 2 , addr = " << static_cast<void*> (const_cast<char *> (tmp)) << endl;

return 0;
}


代码2:

10test.cpp

#include <iostream>
#include <cstring>
using namespace std;

int main()
{
string ss("abcdefghigklmnopq");

const char *tmp = ss.c_str();
cout << "ss.c_str() 1 = " << tmp << endl;
cout << "ss.c_str() 1 , addr = " << static_cast<void*> (const_cast<char *> (tmp)) << endl;

ss = "1234";

cout << "ss.c_str() 2 = " << tmp << endl;
cout << "ss.c_str() 2 , addr = " << static_cast<void*> (const_cast<char *> (tmp)) << endl;

return 0;
}


输出结果1:

[bnms@bogon test]$ g++ 9test.cpp
[bnms@bogon test]$ ./a.out
ss.c_str() 1 = abcdefghigklmnopq
ss.c_str() 1 , addr = 0x1b89028
ss.c_str() 2 = abcdefghigklmnopq
ss.c_str() 2 , addr = 0x1b89028


输出结果2:
[bnms@bogon test]$ g++ 10test.cpp
[bnms@bogon test]$ ./a.out
ss.c_str() 1 = abcdefghigklmnopq
ss.c_str() 1 , addr = 0x2252028
ss.c_str() 2 = 1234
ss.c_str() 2 , addr = 0x2252028


...全文
346 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2017-08-21
  • 打赏
  • 举报
回复
难道string的c_str()对应源代码不在include\string文件中吗?
neigedg 2017-08-21
  • 打赏
  • 举报
回复
把ss.c_str()的地址打印出来,可以验证一楼的回答。 9test.cpp: #include <iostream> #include <cstring> using namespace std; int main() { string ss("abcdefghigklmnopq"); const char *tmp = ss.c_str(); cout << "ss.c_str() 1 = " << tmp << endl; cout << "ss.c_str() 1 , addr = " << static_cast<void*> (const_cast<char *> (ss.c_str())) << endl; ss = "bacdbefghigkgilfgimnopq"; cout << "ss.c_str() 2 = " << tmp << endl; cout << "ss.c_str() 2 , addr = " << static_cast<void*> (const_cast<char *> (ss.c_str())) << endl; return 0; } 代码2: 10test.cpp #include <iostream> #include <cstring> using namespace std; int main() { string ss("abcdefghigklmnopq"); const char *tmp = ss.c_str(); cout << "ss.c_str() 1 = " << tmp << endl; cout << "ss.c_str() 1 , addr = " << static_cast<void*> (const_cast<char *> (ss.c_str())) << endl; ss = "1234"; cout << "ss.c_str() 2 = " << tmp << endl; cout << "ss.c_str() 2 , addr = " << static_cast<void*> (const_cast<char *> (ss.c_str())) << endl; return 0; } 输出结果1: [bnms@bogon test]$ g++ 9test.cpp [bnms@bogon test]$ ./a.out ss.c_str() 1 = abcdefghigklmnopq ss.c_str() 1 , addr = 0x242f028 ss.c_str() 2 = abcdefghigklmnopq ss.c_str() 2 , addr = 0x242f068 输出结果2: [bnms@bogon test]$ g++ 10test.cpp [bnms@bogon test]$ ./a.out ss.c_str() 1 = abcdefghigklmnopq ss.c_str() 1 , addr = 0x247f028 ss.c_str() 2 = 1234 ss.c_str() 2 , addr = 0x247f028
neigedg 2017-08-21
  • 打赏
  • 举报
回复
感谢各位的解答,一楼正解。
xskxzr 2017-08-20
  • 打赏
  • 举报
回复
【译制】每个 C 程序员都应知道的关于未定义行为的那点事 楼上都强行钦定string的实现吗(虽然大部分编译器都是这么干的)……
sdghchj 2017-08-18
  • 打赏
  • 举报
回复

 int main()
 {
     string ss("abcdefghigklmnopq");

     const char *tmp = ss.c_str();
     cout << "ss.c_str() 1 = " << tmp << endl;
     cout << "ss.c_str() 1 , addr = " << static_cast<void*> (const_cast<char *> (tmp)) << endl;

     ss = "bacdbefghigkgilfgimnopq";

     cout << "ss.c_str() 2 = " << tmp << endl;
     cout << "ss.c_str() 2 , addr = " << static_cast<void*> (const_cast<char *> (tmp)) << endl;

     tmp = ss.c_str();
     cout << "ss.c_str() 3 = " << tmp << endl;
     cout << "ss.c_str() 3 , addr = " << static_cast<void*> (const_cast<char *> (tmp)) << endl;

     return 0;
 }
ss.c_str() 1 = abcdefghigklmnopq ss.c_str() 1 , addr = 0xf516b0 ss.c_str() 2 = xo ss.c_str() 2 , addr = 0xf516b0 ss.c_str() 3 = bacdbefghigkgilfgimnopq ss.c_str() 3 , addr = 0xf56f48
Really_want 2017-08-18
  • 打赏
  • 举报
回复
用你的代码,运行结果如下,供参考:

sdghchj 2017-08-18
  • 打赏
  • 举报
回复
这得看string的内部实现了,跟vector类似。 当赋新值的长度比原有内存大时,需要开辟新的连续内存空间(同时释放原内存)来存储。就出现了前面的情况。 反之原有内存足以容纳新字符串时,就直接使用原有的内存。
我看你有戏 2017-08-18
  • 打赏
  • 举报
回复
是跟str字符串的长度有关系,超过一定长度时,底层会重新去开辟一块内存,把整个字符串复制过去,之前块内存会被释放
SK_AJIE 2017-08-18
  • 打赏
  • 举报
回复
一楼正解,和string的容量有关,超出容量了就会重新开辟内存
jena_wy 2017-08-18
  • 打赏
  • 举报
回复
http://blog.csdn.net/wyyy2088511/article/details/77335195,看到你打印的是地址,常量指针。
赵4老师 2017-08-18
  • 打赏
  • 举报
回复
http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素

64,642

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧