8

std::vectorの容量を正確なサイズに縮小して、追加のメモリを解放したいと思います。標準的なトリックは、ここで説明されているもののようです:

template< typename T, class Allocator >
void shrink_capacity(std::vector<T,Allocator>& v)
{
   std::vector<T,Allocator>(v.begin(),v.end()).swap(v);
}

縮小縮小の要点はメモリを節約することですが、この方法は最初にディープ コピーを作成してからインスタンスを交換するのではないでしょうか? では、ある時点で (コピーが作成されると)、メモリ使用量が 2 倍になるのでしょうか?

その場合、メモリにやさしいシュリンク トゥ フィットの方法はありますか? (私の場合、ベクトルは非常に大きく、いつでもオリジナルとそのコピーの両方をメモリに保持する余裕はありません。)

4

2 に答える 2

3

では、配列のサイズを変更したい場合、どうしますか? 新しいものを作成し、すべての値をコピーする必要があります-個別に、またはmemcpyなどで。C または C++ では、配列のサイズを実際に変更することはできません。

std::vectorストレージに配列を使用して実装されることがほぼ保証されています(IIRC、標準は配列であることを保証していませんが、各操作の効率など、APIのさまざまな要件を満たすことができるのは配列だけです; したがって、実際には、その保証が明示的でなくても保証されます)。配列を使用して実装され、コピーせずに配列のサイズを変更できないため、コピーせずにベクトルのサイズを変更することはできません。

理論的には、shrink_capacity()サイズ要件を一時的に 2 倍にする必要があるという事実を隠す関数をstd::vector作成できますが、現時点ではそのような関数がないため、実際には明示的なコピーを作成する必要があります。スワップ トリックは、そのための優れた方法です。

このような場合にメモリを本当に気にする場合は、ベクターにオブジェクトを直接保持させる代わりに、ポインター (またはスマート ポインター) を使用することができます。これは完全に望ましいことではないかもしれませんが、必要なメモリ量を減らすことができます。

于 2010-04-23T01:15:01.277 に答える
-1

新しいサイズが元のサイズの半分である場合、新しいベクトル (またはベクトルがこれを実行できない場合はストレート dynaimc 配列) を古いベクトルの未使用の端部に配置することで回避できる場合があります。ベクトルがそのメモリ領域に情報を保存するかどうかは不明なので、これは非常にハッキーで恐ろしいことです。しかし、それはアイデアです。

そういえば、オリジナルで最後に使ったインデックスからオリジナルの未使用領域の奥に情報を逆にコピーする memMove() 型の操作でデータが保存されます。これを配列の新しい配置にした場合、元のメモリ領域の真ん中に新しいデータが存在する場所を指すことができます。その場での移動自体。

于 2010-04-23T01:21:20.903 に答える