Aslında, eklenen öğe sayısı için minimum düzeyde gerekenden daha fazla bellek ayıran her türlü veri yapısının uygulanması gerekir (yani, bir kerede bir düğümü ayıran bağlantılı bir yapı dışında herhangi bir şey).
Al konteynerler gibi unordered_map
, vector
ya da deque
. Bunların hepsi, her bir ekleme için yığın tahsisi gerektirmemek için şimdiye kadar eklediğiniz öğeler için minimum düzeyde gerekenden daha fazla bellek ayırır. vector
En basit örnek olarak kullanalım .
Yaptığınızda:
vector<Foo> vec;
// Allocate memory for a thousand Foos:
vec.reserve(1000);
... aslında bin Foo yapmaz. Onlar için sadece bellek ayırır / ayırır. Eğer vector
yeni burada yerleşim kullanın vermedi, varsayılan-inşa olurdu Foos
biryere yanı sıra bile bile ilk etapta eklenen asla elemanları kendi yıkıcı çağırmak zorunda.
Tahsis! = İnşaat, Serbest! = Yıkım
Genel olarak yukarıdaki gibi birçok veri yapısını uygulamak için konuşursak, bellek ayırmayı ve öğeleri oluşturmayı bölünmez bir şey olarak ele alamazsınız ve aynı zamanda belleği serbest bırakmayı ve öğeleri yok etmeyi bölünmez bir şey olarak ele alamazsınız.
Gereksiz yere sol ve sağ gereksiz kurucuları ve yıkıcıları çağırmak için bu fikirler arasında bir ayrım olmalıdır ve bu nedenle standart kütüphane std::allocator
(hafızayı ayırdığında / serbest bıraktığında öğeleri oluşturmaz veya imha etmez *) fikrini yeni yerleşimi kullanarak öğeleri el ile yapılandıran ve yıkıcıların açık çağrılarını kullanarak öğeleri el ile yok eden, onu kullanan kaplar.
- Tasarımından nefret ediyorum,
std::allocator
ama bu sıralamamaktan kaçınacağım farklı bir konu. :-D
Her neyse, çok fazla kullanma eğilimindeyim, çünkü mevcut olanlar açısından inşa edilemeyen bir dizi genel amaçlı standart uyumlu C ++ kapları yazdım. Bunların arasında, birkaç yıl önce yaygın durumlarda yığın tahsislerinden kaçınmak için oluşturduğum küçük bir vektör uygulaması ve bellek verimli bir üçlü (bir seferde bir düğüm ayırmaz) bulunur. Her iki durumda da onları mevcut kapları kullanarak gerçekten uygulayamadım ve bu nedenle placement new
gereksiz sol ve sağdaki şeylere yapıcıları ve yıkıcıları gereksiz yere çağırmaktan kaçınmak zorunda kaldım .
Doğal olarak, ücretsiz bir liste gibi, nesneleri ayrı ayrı tahsis etmek için özel ayırıcılar ile çalışırsanız, genellikle placement new
bu şekilde de kullanmak istersiniz (istisna güvenliği veya RAII ile uğraşmayan temel örnek):
Foo* foo = new(free_list.allocate()) Foo(...);
...
foo->~Foo();
free_list.free(foo);