Giriş
Allocator STL'in en az bilinen ve kullanılan özelliklerinden bir tanesi. Bu sınıf tüm STL veri yapıları ile kullanılır. Açıklaması şöyle
C++11'den önce allocator nesneleri state tutmazdı. Artık tutabiliyor.
Allocator Bellek Yönetimi Ve Nesne Kurulumunun Birbirinden Ayrılmasını Sağlar
Kod ile örmek vermek gerekirse
2 ve 3 ile nesneler ayrılan bellek alanına kurulur
4 ile nesneler yok edilir ancak allocator ile ayrılan bellek alanı korunur.
En sonunda vector yok olduğu için bellek alanı iade edilir.
Copy Constructor
Allocator bir şekilde copy constructor metodunu desteklemeli ama niçin anlamadım.
Allocator içinde bazı typedefler kullanılır.
Bunlar pointer ve const_pointer tipleridir.
Malloc gibi çalışır. Her allocator haliyle bir allocate metoduna sahip olmalı.
İmzası şöyle
C++11 ile şöyle yaparız.
Açıklaması şöyle.
Allocator'ın en fazla ne kadarlık bellek ayırabileceğini gösterir.
Bu metod bir şekilde sağlanmalı. Sebebini bilmiyorum. Açıklaması şöyle.
C++11 ile bu metod isteğe bağlı hale geldi. Bu metodu sağlamazsak allocator_traits bir metod sağlar.
Örnek
Şöyle yaparız.
Elimizde şöyle bir yapı olsun. void allocator char allocator olarak rebind edilir.
Şöyle kullanılır.
Allocator STL'in en az bilinen ve kullanılan özelliklerinden bir tanesi. Bu sınıf tüm STL veri yapıları ile kullanılır. Açıklaması şöyle
The std::allocator class template is the default Allocator used by all standard library containers if no user-specified allocator is provided.
Bu sınıf heap'ten bellek alır. Açıklaması şöyle
StateAllocates n * sizeof(T) bytes of uninitialized storage by calling ::operator new(std::size_t)
C++11'den önce allocator nesneleri state tutmazdı. Artık tutabiliyor.
Allocator Bellek Yönetimi Ve Nesne Kurulumunun Birbirinden Ayrılmasını Sağlar
Kod ile örmek vermek gerekirse
std::vector<X> v;
v.reserve(4); // (1)
v.push_back( X{} ); // (2)
v.push_back( X{} ); // (3)
v.clear(); // (4)
1. allocator ile bellek ayrılmasını sağlar.2 ve 3 ile nesneler ayrılan bellek alanına kurulur
4 ile nesneler yok edilir ancak allocator ile ayrılan bellek alanı korunur.
En sonunda vector yok olduğu için bellek alanı iade edilir.
Copy Constructor
Allocator bir şekilde copy constructor metodunu desteklemeli ama niçin anlamadım.
Allocator içinde bazı typedefler kullanılır.
Bunlar pointer ve const_pointer tipleridir.
template <typename T>
class my_allocator
{
public:
typedef size_t size_type;
typedef T* pointer;
typedef const T* const_pointer;
}
allocate metoduMalloc gibi çalışır. Her allocator haliyle bir allocate metoduna sahip olmalı.
İmzası şöyle
pointer allocate(size_type n){
...
}
veya şöyle. İkinci imza tam olarak ne işe yarıyor bilmiyorum.pointer allocate(size_type num, const_pointer = 0) {
...
}
ÖrnekC++11 ile şöyle yaparız.
template <typename T>
struct aligned_allocator {
typedef T value_type
T* allocate(std::size_t num) {
void* ptr = nullptr;
if (posix_memalign(&ptr,4096,num*sizeof(T)))
throw std::bad_alloc();
return reinterpret_cast<T*>(ptr);
}
void deallocate(T* p, std::size_t num) {
free(p);
}
};
std::vector<int16_t,aligned_allocator<int16_t>> v(64);
std::vector<uint16_t,aligned_allocator<uint16_t>> v(64);
std::vector<int16_t,aligned_allocator<int16_t>> v (64);
deallocate metoduAçıklaması şöyle.
Free gibi çalışır. Her allocator haliyle bir deallocate metoduna sahip olmalı.İmzası şöylevoid deallocate( T* p, std::size_t n );
"The argument n must be equal to the first argument of the call to allocate() that originally produced p; otherwise, the behavior is undefined."
// deallocate memory at 'p'
void deallocate(pointer p, size_type num=0) {
...
}
max_sizeAllocator'ın en fazla ne kadarlık bellek ayırabileceğini gösterir.
Şöyle yaparızReturns the largest value that can be passed meaningfully to allocate() to allocate storage
size_type max_size(){
return 1;
}
operator != metoduBu metod bir şekilde sağlanmalı. Sebebini bilmiyorum. Açıklaması şöyle.
You are missing !=, ==, cross-type implicit conversion, and, as pertinent here, rebind.Yani şu allocator sınıfı yeterli değil.
template<typename Tag, typename T>
struct MyAllocator
{
using value_type = typename std::allocator<T>::value_type;
T* allocate(std::size_t n)
{
Tag::logAllocation();
return std::allocator<T>{}.allocate(n);
}
void deallocate(T* p, std::size_t n)
{
Tag::logDeallocation();
std::allocator<T>{}.deallocate(p, n);
}
};
rebind metoduC++11 ile bu metod isteğe bağlı hale geldi. Bu metodu sağlamazsak allocator_traits bir metod sağlar.
Örnek
Şöyle yaparız.
typedef typename _Alloc::template rebind<_Ty>::other _Alty;
ÖrnekElimizde şöyle bir yapı olsun. void allocator char allocator olarak rebind edilir.
template <typename Alloc = std::allocator<void> >
struct C {
using allocator_type = Alloc;
bip::vector<char, typename Alloc::template rebind<char>::other> data;
C(Alloc alloc = {}) : data(alloc) {}
void add_char() {
data.push_back('x');
}
};
STL sınıfları ile kullanımıŞöyle kullanılır.
std::vector<T,tbb::scalable_allocator<T> >
Boost ile gelen bir sürü allocator da var. Bunlardan bir tanesi aligned_allocator. Şöyle kullanılır. Her bir eleman arasına 16 byte boşluk ekler.#include <boost/align/aligned_allocator.hpp>
#include <vector>
int main()
{
std::vector<int, boost::alignment::
aligned_allocator<int, 16> > v(100);
}
Hiç yorum yok:
Yorum Gönder