c++ - 使用 op[] 修改 std::string 超出其大小的影响?

标签 c++ stdstring

我对如何处理超出其大小的 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/

相关文章:

c++ - 如何在 JIT 代码生成后检索 llvm::Instruction 地址?

c++ - EXC_BAD_ACCESS 与 OSX 中的 wxWidgets

c++ - 在 C++11 中,将引用/指针返回到 std::string 中某个位置的最高效方法是什么?

c++ - std::string 中的段错误

c++ - std::string 在 vi​​sual studio 上的具体行为?

c++ - msvc is_copy_assignable 始终为真?

c++ - 从函数返回类对象的不同行为

c++ - 现代 OpenGL + SDL2 三角形未显示

c++ - 我如何追溯错误

c++ - 如何从作为模式给出的 std::string 中提取单词?