使用op []修改std :: string超出其大小的效果?

时间:2014-05-04 15:27:26

标签: 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 size / capacity:3,3 str after:abc
c_str之后:abcde
str size / capacity:3,3

1 个答案:

答案 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所指出的那样,你可能已经看过垃圾了,除非你有幸在你的额外角色之后有一个额外的零字节。