我对如何处理超出其大小的std :: string的处理感到困惑?在我尝试的一个例子中,它允许我使用op [](and I'm aware that standard doesn't stop you from doing it)修改超出其大小的字符串。但是,当我使用cout打印字符串时,它会打印原始字符串,但是当我打印cstr()返回的内容时,它会打印修改后的版本。它如何跟踪两种尺寸(3& 5)?
#include <string>
#include <iostream>
using namespace std;
int main(void) {
std::string a = "abc";
cout << "str before : " << a << endl;
const char * charPtr = a.c_str ();
cout << "c_str before : " << charPtr << endl;
cout << "str size / capacity : " << a.size () << ", " << a.capacity () << endl;
a[3] = 'd';
a[4] = 'e';
cout << "str after : " << a << endl;
const char * charPtr2 = a.c_str ();
cout << "c_str after : " << charPtr2 << endl;
cout << "str size / capacity : " << a.size () << ", " << a.capacity () << endl;
return 0;
}
输出:
str之前:abc
c_str之前:abc
str size / capacity:3,3
str after:abc
c_str之后:abcde
str size / capacity:3,3
答案 0 :(得分:1)
虽然你已经有一个正确的评论说行为是未定义的,但也有一些值得给出的实际答案。
C ++ string
对象可以包含您喜欢的任何字符序列。 C风格的字符串由第一个'\0'
终止。因此,C ++ string
对象必须存储其他的大小,而不是搜索'\0'
:它可能包含嵌入式'\0'
字符。
#include <string>
#include <iostream>
int main() {
std::string s = "abc";
s += '\0';
s += "def";
std::cout << s << std::endl;
std::cout << s.c_str() << std::endl;
}
运行它,并通过cat -v
管道输出以使控制字符可见,我看到:
abc^@def abc
这解释了您所看到的内容:您正在覆盖'\0'
终结符,但您不会覆盖单独存储的大小。
正如kec所指出的那样,你可能已经看过垃圾了,除非你有幸在你的额外角色之后有一个额外的零字节。