allocator
Főnév
allocator (tsz. allocators)
- (informatika) A C++ számítógépes programozásban az allokátorok a C++ Standard Library összetevői. A szabványos könyvtár számos adatstruktúrát biztosít, például listát és halmazt, amelyeket általában konténereknek neveznek. Ezeknek a tárolóknak a közös jellemzője, hogy a program végrehajtása során méretüket megváltoztathatják. Ennek eléréséhez általában valamilyen dinamikus memóriafoglalásra van szükség. Az allokátorok kezelik az összes memóriafoglalási és -felszabadítási kérelmet egy adott tárolóhoz. A C++ Standard Library általános célú elosztókat biztosít, amelyek alapértelmezés szerint használatosak, azonban a programozó egyéni lefoglalókat is biztosíthat.
Az allokátorokat Alexander Stepanov találta fel a Standard Template Library (STL) részeként. Eredetileg a könyvtár rugalmasabbá és a mögöttes memóriamodelltől függetlenebbé tételére készültek, lehetővé téve a programozók számára, hogy egyéni mutató- és referenciatípusokat használjanak a könyvtárral. Az STL-nek a C++ szabványba való átvétele során azonban a C++ szabványügyi bizottság felismerte, hogy a memóriamodell teljes absztrakciója elfogadhatatlan teljesítménybüntetéssel járna. Ennek orvoslására az allokátorokkal szemben támasztott követelményeket szigorították. Ennek eredményeként az allokátorok által biztosított testreszabási szint korlátozottabb, mint ahogyan azt Stepanov eredetileg elképzelte.
Ennek ellenére számos forgatókönyv létezik, amikor a testreszabott allokátorok kívánatosak. Az egyéni allokátorok írásának leggyakoribb okai közé tartozik az allokációk teljesítményének javítása memóriakészletek használatával, valamint a különböző típusú memóriákhoz, például a megosztott memóriához vagy a szemétből gyűjtött memóriához való hozzáférés beágyazása. Különösen a kis memóriamennyiséget gyakran lefoglaló programok számára jelenthet nagy hasznot a speciális lefoglalók, mind a futási idő, mind a memóriaterület tekintetében.
A C++ memóriaallokáció egyik fontos része az std::allocator, amely az STL konténerek memóriakezeléséért felelős. Az allocator egy eszköz arra, hogy egyedi módon kezeljük a dinamikus memóriafoglalást anélkül, hogy közvetlenül a new és delete operátorokat kellene használni.
1. Mi az std::allocator?
Az std::allocator egy sablon osztály, amely lehetővé teszi a memória kezelését alacsonyabb szinten, mint az STL konténerek alapértelmezett megoldása.
Fő céljai:
✅ Memória foglalása és felszabadítása
✅ Objektumok konstruálása és destruktálása
✅ Jobb teljesítmény elérése speciális esetekben
✅ STL konténerekkel való kompatibilitás
Az alapértelmezett STL konténerek (például std::vector, std::map, stb.) az std::allocator segítségével kezelik a memóriát.
2. std::allocator alapvető működése
Az std::allocator öt fő műveletet támogat:
allocate(n)– Memória foglalásandarab elem számára (konstrukció nélkül).
deallocate(p, n)– Foglalt memória felszabadítása.
construct(p, args...)– Objektum létrehozása egy adott memóriacímre.
destroy(p)– Objektum destruktálása a memóriában.
max_size()– Megmondja, hogy maximum hány elem foglalható.
3. Példa – Egyszerű std::allocator használat
Ebben a példában bemutatjuk, hogyan foglalunk és szabadítunk fel memóriát std::allocator segítségével.
#include <iostream>
#include <memory> // std::allocator-hoz szükséges
int main() {
std::allocator<int> alloc; // Allokátor objektum létrehozása
// Memória foglalása 5 egész szám számára
int* ptr = alloc.allocate(5);
// Értékek beállítása a foglalt memóriában
for (int i = 0; i < 5; i++) {
alloc.construct(ptr + i, i * 10); // Konstruktálás a memóriában
}
// Kiíratás
for (int i = 0; i < 5; i++) {
std::cout << ptr[i] << " ";
}
// Objektumok megsemmisítése
for (int i = 0; i < 5; i++) {
alloc.destroy(ptr + i);
}
// Memória felszabadítása
alloc.deallocate(ptr, 5);
return 0;
}
Kimenet:
0 10 20 30 40
Fontos részletek:
- Az
allocate(5)lefoglal egy 5 elemnyi memóriaterületet, de az elemeket nem inicializálja. - A
construct()segítségével létrehozzuk az objektumokat a memóriaterületen. - A
destroy()felszabadítja az objektumokat, mielőtt adeallocate()teljesen felszabadítaná a memóriát.
4. Hogyan használják az std::allocator-t STL konténerek?
Az STL konténerek, például std::vector, az std::allocator segítségével kezelik a memóriát. Az alábbi példa bemutatja, hogyan adjuk meg egy konténernek saját allokátort.
#include <iostream>
#include <vector>
#include <memory>
int main() {
std::vector<int, std::allocator<int>> v; // Vector std::allocator használatával
v.push_back(1);
v.push_back(2);
v.push_back(3);
for (int x : v) {
std::cout << x << " ";
}
return 0;
}
Kimenet:
1 2 3
- Itt az
std::allocatora háttérben működik, és kezeli a memóriafoglalást.
5. Egyedi allokátorok létrehozása
Az std::allocator helyett létrehozhatunk saját allokátort, amely eltérő módon kezeli a memóriafoglalást.
Példa – Egyedi MyAllocator osztály
#include <iostream>
#include <memory>
template <typename T>
struct MyAllocator {
using value_type = T;
T* allocate(std::size_t n) {
std::cout << "Custom allocate: " << n << " element\n";
return static_cast<T*>(::operator new(n * sizeof(T))); // Nyers memóriafoglalás
}
void deallocate(T* p, std::size_t n) {
std::cout << "Custom deallocate: " << n << " element\n";
::operator delete(p); // Memória felszabadítása
}
};
int main() {
std::allocator<int> defaultAlloc;
MyAllocator<int> customAlloc;
int* ptr = customAlloc.allocate(5);
customAlloc.deallocate(ptr, 5);
return 0;
}
Kimenet:
Custom allocate: 5 element Custom deallocate: 5 element
- Az egyedi
MyAllocatorkiírja, amikor memóriát foglal és szabadít fel.
6. std::allocator_traits – Az allokátorok fejlettebb kezelése
A std::allocator_traits egy segédsablon, amely egységesíti az allokátorok működését. Használata megkönnyíti az egyedi allokátorok írását.
Példa – allocator_traits használata
#include <iostream>
#include <memory>
int main() {
std::allocator<int> alloc;
std::allocator_traits<std::allocator<int>>::pointer p = alloc.allocate(5);
std::allocator_traits<std::allocator<int>>::construct(alloc, p, 42);
std::cout << "Elso elem: " << *p << std::endl;
std::allocator_traits<std::allocator<int>>::destroy(alloc, p);
alloc.deallocate(p, 5);
return 0;
}
Előnyök: - A std::allocator_traits segít általánosabbá tenni az allokátorok használatát. - Az allocate(), construct(), destroy() és deallocate() hívások egységesek lesznek.
7. Mikor érdemes egyedi allocator-t használni?
✅ Nagy teljesítményű alkalmazásokban – pl. grafikus motorok, adatbázis-kezelők.
✅ Ha saját memóriakezelést akarunk – például memóriakészleteket (memory pool).
✅ Speciális memóriahasználati esetekben – például amikor szigorúan kell szabályozni a memóriafoglalást.
Mikor NEM szükséges?
❌ Ha az alapértelmezett std::allocator teljesítménye megfelelő.
❌ Ha az alkalmazás nem igényel speciális memóriaoptimalizációt.
Összegzés
✔ Az std::allocator egy alacsony szintű memóriaallokációs mechanizmus az STL számára.
✔ Lehetővé teszi az objektumok egyedi létrehozását és felszabadítását.
✔ STL konténerekkel kompatibilis, és fejlettebb memóriakezelést biztosít.
✔ Egyedi allokátorokat hozhatunk létre teljesítményoptimalizálásra.
✔ Ha speciális igények merülnek fel, a std::allocator_traits segíthet az egységesebb kódban.