I'm bit puzzled by how modifying a std::string beyond its size is handled? In an example I tried, it allowed me to modify the string beyond its size using op[] (and I'm aware that standard doesn't stop you from doing it). However, when I print the string using cout it prints the original string but when I print whats returned by cstr (), it prints the modified version. How does it keep track of both sizes (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;
}

output :
str before : abc
c_str before : abc
str size / capacity : 3, 3
str after : abc
c_str after : abcde
str size / capacity : 3, 3

有帮助吗?

解决方案

Although you already got a correct comment saying the behaviour is undefined, there is something worthy of an actual answer too.

A C++ string object can contain any sequence of characters you like. A C-style string is terminated by the first '\0'. Consequently, a C++ string object must store the size somewhere other than by searching for the '\0': it may contain embedded '\0' characters.

#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;
}

Running this, and piping the output through cat -v to make control characters visible, I see:

abc^@def
abc

This explains what you're seeing: you're overwriting the '\0' terminator, but you're not overwriting the size, which is stored separately.

As pointed out by kec, you might have seen garbage except you were lucky enough to have an additional zero byte after your extra characters.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top