5

I have this snippet from Thinking in C++.

#include <iostream>
#include <string>

int main ()
{
string bigNews("I saw Elvis in a UFO. ");
cout << bigNews << endl;
 bigNews.insert(0, " thought I ");
cout << bigNews << endl;
cout << "Size = " << bigNews.size() << endl;
cout << "Capacity = "
<< bigNews.capacity() << endl;
bigNews.append("I've been working too hard.");
cout << bigNews << endl;
cout << "Size = " << bigNews.size() << endl;
cout << "Capacity = "
<< bigNews.capacity() << endl;
  return 0;
}

And I get output as shown below:

I saw Elvis in a UFO. 
 thought I I saw Elvis in a UFO. 
Size = 33
Capacity = 44
 thought I I saw Elvis in a UFO. I've been working too hard.
Size = 60
Capacity = 88

I can figure out why the size increases, but I am not able to make out how the Capacity increases?

What i know is Capacity is the string buffer where we can Pushback, but how that space is allocated?

4

2 回答 2

12

capacity is the maximum number of characters that the string can currently hold without having to grow. size is how many characters actually exist in the string. The reason they're separate concepts is that allocating memory is generally inefficient, so you try to allocate as rarely as possible by grabbing more memory than you actually need at one time. (Many data structures use a "doubling" method where, if they hit their capacity of N and need more space, they will allocate 2*N space, to avoid having to reallocate again any time soon.)

capacity will increase automatically as you use the string and require more space. You can also manually increase it using the reserve function.

于 2013-09-25T04:41:01.827 回答
3

From the documentation:

capacity()

returns the number of characters that can be held in currently allocated storage (public member function)

So, it is the allocation size of the internal buffer. What you see is its size doubling when it's exhausted -- this is a common technique for using dynamically-sized buffers efficiently, and it's called "exponential storage expansion". What it boils down to is basically this:

void resize_buffer(char **buf, size_t *cap, size_t newsize)
{
    while (newsize > *cap)
        *cap *= 2;

    *buf = realloc(*buf, *cap);
}

(Of course, this is largely simplified, don't use this for actual reallocation code in production.) Probably your implementation of std::string is using this trick, that's why you see the buffer size going up by 100%.

于 2013-09-25T04:47:13.873 回答