You can easily see the behavior of your implementation by calling std::string::capacity at different times. In general, I would be surprised if any implementation ever had a three-character buffer. (Not words, but bytes, at least on most modern machines.) In practice, implementations differ and also vary depending on how the new length occurs: with g ++, for example, deleting characters using std::string::erase will not reduce the capacity of the row, but assigning a new, smaller row. VC ++ does not reduce capacity in any case. (In general, VC ++ and g ++ have very different strategies for managing memory in strings.)
EDIT:
Given other answers (which do not even correspond to the usual practice): here is a small test program that I used to check my statements above (although I really did not need this for g ++ - I know that the internals of the implementation are pretty good):
#include <string> #include <iostream> #include <iomanip> template<typename Traits> void test() { std::string s; size_t lastSeen = -1; std::cout << Traits::name() << ": Ascending:" << std::endl; while ( s.size() < 150 ) { if ( s.capacity() != lastSeen ) { std::cout << " " << std::setw( 3 ) << s.size() << ": " << std::setw( 3 ) << s.capacity() << std::endl; lastSeen = s.capacity(); } Traits::grow( s ); } std::cout << Traits::name() << ": Descending: " << std::endl; while ( s.size() != 0 ) { Traits::shrink( s ); if ( s.capacity() != lastSeen ) { std::cout << " " << std::setw( 3 ) << s.size() << ": " << std::setw( 3 ) << s.capacity() << std::endl; lastSeen = s.capacity(); } } std::cout << "Final: capacity = " << s.capacity() << std::endl; } struct Append { static void grow( std::string& s ) { s += 'x'; } static void shrink( std::string& s ) { s.erase( s.end() - 1 ); } static std::string name() { return "Append"; } }; struct Assign { static void grow( std::string& s ) { s = std::string( s.size() + 1, 'x' ); } static void shrink( std::string& s ) { s = std::string( s.size() - 1, 'x' ); } static std::string name() { return "Assign"; } }; int main() { test<Append>(); test<Assign>(); return 0; }
Give it a try. The results are very instructive.
source share