5

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

そして、以下に示すような出力が得られます。

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

サイズが増加する理由はわかりますが、容量がどのように増加するかわかりませんか?

私が知っているのは、容量はプッシュバックできる文字列バッファーですが、そのスペースはどのように割り当てられるのでしょうか?

4

2 に答える 2

12

capacity文字列が拡張することなく現在保持できる最大文字数です。size文字列に実際に存在する文字数です。それらが別々の概念である理由は、メモリの割り当ては一般的に非効率的であるため、一度に実際に必要とするよりも多くのメモリを取得して、可能な限りめったに割り当てないようにするためです。(多くのデータ構造は「倍増」方式を使用しており、容量にN達してさらにスペースが必要になった場合、2*Nすぐに再割り当てする必要がないようにスペースを割り当てます。)

capacity文字列を使用してより多くのスペースが必要になると、自動的に増加します。関数を使用して手動で増やすこともできreserveます。

于 2013-09-25T04:41:01.827 に答える
3

ドキュメントから:

capacity()

現在割り当てられているストレージに保持できる文字数を返します (パブリック メンバー関数)

つまり、内部バッファの割り当てサイズです。使い果たされると、サイズが 2 倍になります。これは、動的にサイズ変更されたバッファーを効率的に使用するための一般的な手法であり、「指数関数的ストレージ拡張」と呼ばれます。要約すると、基本的には次のとおりです。

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

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

(もちろん、これは大幅に単純化されています。本番環境での実際の再割り当てコードには使用しないでください。) おそらく、 の実装でstd::stringこのトリックが使用されているため、バッファ サイズが 100% 増加します。

于 2013-09-25T04:47:13.873 に答える