As a part of vector implementation I have to implement an allocator using functions malloc()
and free()
given the below interface:
class Allocator
manages memory for class vector:
template<class T>
class Allocator {
public:
// function members
T* allocate(int n);
void deallocate(T* p, int n);
void construct(T* p, const T& v);
void destroy(T* p);
};
class Allocator
member implementations:
/*
Function: allocate()
Use: allocator_object.allocator(num_of_elements)
Implicit in vector_base constructor.
It wraps malloc(); Throws bad_alloc
if allocation unsuccessful.
*/
template <class T>
T* Allocator<T>::allocate(int n) {
try {
std::auto_ptr<T> mem_ptr = reinterpret_cast<T*>(malloc(n * sizeof(T)));
} catch (std::bad_alloc& e) {
std::cerr <<"bad_alloc caught: "<< e.what() <<'\n';
throw;
}
return mem_ptr.release();
}
/*
Function: deallocate()
Use: allocator_object.deallocate(mem_ptr, redundant_par);
Implicit in base_vector destructor.
It returns memory to free store.
First argument is the pointer returned by malloc().
*/
template <class T>
void Allocator<T>::deallocate(T* mem_ptr, int n) {
free(mem_ptr);
}
/*
Function: construct()
Use: allocator_object.construct(elem_ptr[i], value)
Implicit in vector_base constructor
and all modifying members of vector.
It assigns the value passed as second
argument to the element with address
held by the pointer passed as a first
argument.
*/
template <class T>
void Allocator<T>::construct(T* p, const T& v = T()) {
*p = v;
}
/*
Function: destroy()
Use: allocator_object.destroy(elem_ptr[i]);
Implicitly in vector members: reserve(), resize();
It assigns type default value to the element
with address held by the pointer passed as argument.
*/
template <class T>
void Allocator<T>::destroy(T* p) {
*p = T(); // ? not sure if right
}
How to check for possible bad allocations from malloc()
in function allocate()
1, is the current method correct?
Is the implementation of function destroy()
correct2, could you give me an example of correct implementation?
There is an additional argument, n
, in function deallocate()
which I can't figure out how(what for) to use.
1. I know I'm using a deprecated std::auto_ptr
, just following the book recommendations wrongly trying to get rid of the pointer in case of bad allocation.
2. I've read the documentation for function destroy()
, but considering the fact that the allocated memory is one contiguous chunk that is free()
d by passing the pointer returned by malloc()
, the only reasonable object destruction is the assignment of a default value.
std::bad_alloc
isn't magically generated. malloc
fails by returning nullptr
and there's nothing which would convert that into an exception. You call malloc
, so you must check the return value manually.
destroy
is wrong for the same reason as construct
is wrong: They're a pair of functions that turn raw memory into an object and back. The normal way to do so is by placement new and direct invocation of the destructor. You're just calling the assignment operator there, which doesn't affect the objects lifetime at all.