Thursday, March 27, 2025

allocator

Overview
Allocators are classes that define memory models to be used by some parts of the Standard Library, and most specifically, by STL containers.

Details
The allocator class template is the default Allocator used by all standard library containers if no user-specified allocator is provided. The default allocator is stateless, that is, all instances of the given allocator are interchangeable, compare equal and can deallocate memory allocated by any other instance of the same allocator type.

Syntax
The syntax is as below. 
template< class T>
class allocator;

//speciation
template<>
class allocator <void>;

NameDescription
TType of objects to be constructed on each element location.

Members
 It defines following types. The explicit specialization for void lacks the member typedefs reference, const_reference, size_type and difference_type. This specialization declares no member functions.
member typedefinition
value_typeElement type
pointerPointer to element
T*
const_pointerConst Pointer to element
const T*
referencereference to element
T&
const_referenceconst reference to element
const T&
size_typeQuantities of elements
size_t
difference_typeDifference between two pointers
ptrdiff_t
propagate_on_container_move_assignmenttrue_type
rebind<U>Its member type other is the equivalent allocator type to allocate elements of type Type.
template< class U >
struct rebind
{
    typedef allocator<U> other;
};
is_always_equaltrue_type

 Functionality
Constructors
NameDescription
  1. allocator()
  2. allocator (const allocator& alloc)
  3. template <class U>
    allocator (const allocator<U>& alloc)
Constructs the default allocator. Since the default allocator is stateless, the constructors have no visible effect.

Methods
NameDescription
  1. pointer address (reference x)
  2. const_pointer address (const_reference x)
 Returns the actual address of x even in presence of overloaded operator&.
pointer allocate
(size_type n, const void *  hint=0)
Attempts to allocate a block of storage with a size large enough to contain n elements of member type value_type (an alias of the allocator's template parameter), and returns a pointer to the first element.
The storage is aligned appropriately for objects of type value_type, but they are not constructed.
In the standard default allocator, the block of storage is allocated using ::operator new one or more times.
The pointer hint may be used to provide locality of reference: the allocator, if supported by the implementation, will attempt to allocate the new memory block as close as possible to hint.
void deallocate
(pointer p, size_type n)
Deallocates the storage referenced by the pointer p, which must be a pointer obtained by an earlier call to allocate().
The argument n must be equal to the first argument of the call to allocate() that originally produced p, otherwise, the behavior is undefined.
Calls ::operator delete(void*) 
The elements in the array are not destroyed by a call to this member function.
size_type max_size()
Returns the maximum theoretically possible value of n, for which the call allocate(n, 0) could succeed.
In most implementations, this returns
numeric_limits<size_type>::max() / sizeof(value_type). 
template< class U, class... Args >
void construct( U* p, Args&&... args )
Constructs an object of type T in allocated uninitialized storage pointed to by p, using global placement-new.
Calls ::new((void*)p) U(forward<Args>(args)...).
template< class U >
void destroy( U* p )
Calls the destructor of the object pointed to by p. Calls p->~U().

Non member Methods
NameDescription
template< class T1, class T2 >
bool operator==
(const allocator<T1>& lhs, const allocator<T2>& rhs ) 
Compares two default allocators. Since default allocators are stateless, two default allocators are always equal. Always returns true.
template< class T1, class T2 >
bool operator!=
(const allocator<T1>& lhs, const allocator<T2>& rhs ) 
Compares two default allocators. Since default allocators are stateless, two default allocators are always equal. Always returns false.

The following Example 13 demonstrates usage of allocator class.
    string numbers[] = {"one", "two", "three", "four"};
    size_t sz = sizeof(numbers);
    
    allocator<string> sal;
    auto sbuf = sal.allocate(sz);
    auto itr = sbuf;
    
    for (auto &s:numbers)
    {
        sal.construct(itr,s);
        ++itr;
    }

    //prints one two three four 
    for (itr = sbuf; itr != sbuf+sz; ++itr)
        cout << *itr  << " ";

    for (auto itr = sbuf; itr != sbuf+sz; ++itr)
       sal.destroy(itr);

    sal.deallocate(sbuf,sz);




No comments:

Post a Comment