我对如何处理超出其大小的 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 大小/容量:3, 3
之后的 str : abc
c_str 之后:abcde
str 大小/容量:3, 3
最佳答案
虽然您已经收到一条正确的评论,说行为未定义,但也有一些值得实际回答的地方。
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 所指出的,您可能已经看到了垃圾,除非您足够幸运,在您的额外字符之后有一个额外的零字节。
关于c++ - 使用 op[] 修改 std::string 超出其大小的影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23457991/