- stl の basic_string の _S_create 関数は、これら 3 つの変数を使用して、実際に割り当てられたサイズを計算します。誰かが理由を知っていますか?
_S_create のインターフェースは
_Rep* _S_create(size_type __capacity, size_type __old_capacity, const _Alloc& __alloc)
なぜ __old_capacity パラメータが必要なのですか?
PS。gnu stl です。
_PageSize
実際のコードは、コメントを読むのが面倒な場合にandを使用する方法をかなりよく説明してい_malloc_header_size
ます (コメントを読まないのはかなり恥ずべきことです。結局のところ、誰かがおそらく私がこの回答を書いたよりも多くの時間をコメントに費やしたからです):
// The standard places no restriction on allocating more memory
// than is strictly needed within this layer at the moment or as
// requested by an explicit application call to reserve().
// Many malloc implementations perform quite poorly when an
// application attempts to allocate memory in a stepwise fashion
// growing each allocation size by only 1 char. Additionally,
// it makes little sense to allocate less linear memory than the
// natural blocking size of the malloc implementation.
// Unfortunately, we would need a somewhat low-level calculation
// with tuned parameters to get this perfect for any particular
// malloc implementation. Fortunately, generalizations about
// common features seen among implementations seems to suffice.
// __pagesize need not match the actual VM page size for good
// results in practice, thus we pick a common value on the low
// side. __malloc_header_size is an estimate of the amount of
// overhead per memory allocation (in practice seen N * sizeof
// (void*) where N is 0, 2 or 4). According to folklore,
// picking this value on the high side is better than
// low-balling it (especially when this algorithm is used with
// malloc implementations that allocate memory blocks rounded up
// to a size which is a power of 2).
そして、セバスチャンはそれを正しく理解しました(ただし、少し異なる方法で書かれています):
// The below implements an exponential growth policy, necessary to
// meet amortized linear time requirements of the library: see
// http://gcc.gnu.org/ml/libstdc++/2001-07/msg00085.html.
// It's active for allocations requiring an amount of memory above
// system pagesize. This is consistent with the requirements of the
// standard: http://gcc.gnu.org/ml/libstdc++/2001-07/msg00130.html
if (__capacity > __old_capacity && __capacity < 2 * __old_capacity)
__capacity = 2 * __old_capacity;
を__pagesize
ここで使用して、少し丸めます...
const size_type __adj_size = __size + __malloc_header_size;
if (__adj_size > __pagesize && __capacity > __old_capacity)
{
const size_type __extra = __pagesize - __adj_size % __pagesize;
__capacity += __extra / sizeof(_CharT);
// Never allocate a string bigger than _S_max_size.
if (__capacity > _S_max_size)
__capacity = _S_max_size;
__size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
}
私が持っている実装には がありませんが、_subpagesize
それは同様の丸めであることを期待しています。
libstdc++を見たり、明確な情報を誰かに尋ねたりせずに、可能な実装の1つは
size_type __actual_capacity = max(__capacity, 2 * __old_capacity);
// do other stuff to create a _Rep.
これにより、確実に必要なだけのメモリ量を保証しながら、幾何学的な拡張が保証されます。