写了五六年的 c++ 现在才发现这个问题,也是有点丢人了😆
短一点的字符串
先搞个代码看看:
#include <bits/stdc++.h>
using namespace std;
int main()
{
string s = "abc";
cout << "sizeof s: " << sizeof(s) << '\n';
cout << &s << '\n';
char *c = &s[0];
cout << (void *)c << '\n';
return 0;
}
运行结果是:
sizeof s: 24
0x16ce1b400
0x16ce1b400
所以能看出来这里 string 类和字符串是存在一个地方的,那么进一步的输出:
#include <bits/stdc++.h>
using namespace std;
string s = "abc";
int main()
{
cout << "sizeof s: " << sizeof(s) << '\n';
cout << &s << '\n';
char *c = &s[0];
cout << (void *)c << "\n\n";
char *tmp = (char *)&s;
for (int i = 0; i <= 23; i++)
{
cout << dec << i << ":" << hex << (int)(*(tmp + i)) << " ";
if ((i + 1) % 8 == 0)
cout << '\n';
}
return 0;
}
输出:
sizeof s: 24
0x104bbc000
0x104bbc000
0:61 1:62 2:63 3:0 4:0 5:0 6:0 7:0
8:0 9:0 10:0 11:0 12:0 13:0 14:0 15:0
16:0 17:0 18:0 19:0 20:0 21:0 22:0 23:3
前三个位置是字符串(其实还有一个’\0’),然后最后一个位置储存的是字符串的长度 3。那么问题来了,如果字符串的长度超过了 23(因为还有一个 ‘\0’ 嘛),那么又会变成啥情况捏。
长一点的字符串
修改一下代码:
#include <bits/stdc++.h>
using namespace std;
string s = string(24, 'A');
int main()
{
cout << "sizeof s: " << sizeof(s) << '\n';
cout << &s << '\n';
char *c = &s[0];
cout << (void *)c << "\n\n";
char *tmp = (char *)&s;
for (int i = 0; i <= 23; i++)
{
cout << dec << i << ":" << hex << (int)(*(tmp + i)) << " ";
if ((i + 1) % 8 == 0)
cout << '\n';
}
return 0;
}
输出:
sizeof s: 24
0x102ba8000
0x11d605f00
0:0 1:5f 2:60 3:1d 4:1 5:0 6:0 7:0
8:18 9:0 10:0 11:0 12:0 13:0 14:0 15:0
16:20 17:0 18:0 19:0 20:0 21:0 22:0 23:ffffff80
这里就很明显发现有了一些变化,可以确认 string 类和字符串被储存到了不同的地方,再次修改代码之后:
#include <bits/stdc++.h>
using namespace std;
string s = string(24, 'A');
int main()
{
cout << "sizeof s: " << sizeof(s) << '\n';
cout << &s << '\n';
char *c = &s[0];
cout << (void *)c << "\n\n";
long *tmp = (long *)&s;
cout << hex << *(tmp) << '\n';
cout << hex << *(tmp + 1) << '\n';
cout << hex << *(tmp + 2) << '\n';
return 0;
}
输出:
sizeof s: 24
0x102558000
0x130e05f00
130e05f00
18
8000000000000020
我们发现前八个字节储存的是字符串真正的位置,中间八个字节是字符串的长度,而最后八个字节(我在网上多番查找之下),我们用这里输出的8000000000000020举例,其中最高位的 “80” 固定来表示字符串被储存在了堆里面,剩下的部分则表示用于储存字符串的堆具体有多大。
作者能力有限,如果有任何错误之处,还请各位指教。(~ ̄▽ ̄)~