In C++ std::allocator
, there are three methods relating to a common concept:
deallocate
destroy
I want to know:
Thank you!
Edit: More specific doubts:
I am sorry to generalize it at first, here are some points I don't understand.
destroy
is used to call the destructor on a object, what does the "object" here means?Thank you again!
If an allocator, A, allocates a region of memory, R, then R can only be deallocated by an allocator that compares equal to A.
Allocators were invented by Alexander Stepanov as part of the Standard Template Library (STL). They were originally intended as a means to make the library more flexible and independent of the underlying memory model, allowing programmers to utilize custom pointer and reference types with the library.
Enhancements to allocators in C++11. The C++11 standard has enhanced the allocator interface to allow "scoped" allocators, so that containers with "nested" memory allocations, such as vector of strings or a map of lists of sets of user-defined types, can ensure that all memory is sourced from the container's allocator.
The 2011 revision of the C++ Standard removed the weasel words requiring that allocators of a given type always compare equal and use normal pointers. These changes make stateful allocators much more useful and allow allocators to manage out-of-process shared memory.
Just the brief descriptions from the cppreference.com documentation explain the differences very clearly for me
"1. What does destructor do? The documentation didn't talk about whether the memory will be released automatically when the destructor is called"
Any memory occupied by the std::allocator
instance will be released as usual.
"2. The
destroy
is used to call the destructor on a object, what does the "object" here means?"
Again to cite the detailed documentation
void destroy( pointer p ); // 1)
template< class U > // 2)
void destroy( U* p );
Calls the destructor of the object pointed to by p
1) Calls((T*)p)->~T()
2) Callsp->~U()
Object in this context means an object of type T
managed by the std::allocator
instance.
The answer to your question lies in the relationship between the delete operation and the object destructor.
deallocate(pointer p,size_type size)
- calls "delete p";
- "delete" implicitly calls the destructor of the object at p;
- frees/deallocates the memory where the object pointed by p was stored
destroy(pointer p)
- calls only the destructor ((T*)p)->~T()
- the memory at addres p will not be freed/deallocated
About destructors
Why does it makes sense to call the destructor without using delete?
a dinamically allocated object could have pointers to allocated objects as member variables. If you want to free that memory without removing the original object which holds the pointers you call the overriden destructor, because the default one would not do that.
In the following example i will try to trivialize the mentioned problem.
example:
template < class T,class U >
class MyClass{
private:
T* first_pointer;
U* second_pointer;
public:
MyClass(){ //constructor:
first_pointer=new T(); //allocate memory for pointer variables
second_pointer=new U(); //with non-argument constructors T() and U()
}
~MyClass(){ //destructor is overriden
delete first_pointer; //because the default-destructor
delete second_pointer; //will not release the memory allocated for
} //first_pointer and second_pointer
void set_first(const T& val){
first_pointer=new T(val);
}
void set_second(const U& val){
second_pointer=new U(val);
}
};
void some_function(void){
MyClass *object;
object=new MyClass();//for example:the allocated object is at memory location 00123A
//lets say that after some time you dont need the memory for "first_pointer" and
//"second_pointer" but you want to keep the memory for "object".
//so we call the destructor.
object->~MyClass();//memory at addres 00123A is still reserved for our object
//but the first_pointer and second_pointer locations
//are deallocated.
//then lets say that after some time we need to set the member variables
object->set_first(T(...)) //arguments depend on the defined constructors
object->set_second(U(...)) //for T and U. Doesn't really matter in this example
//after some time we dont need the object and it's parts at all
//so we call delete on the object
delete object; //calls our destructor to release the memory pointed to
//by first_pointer and second_pointer.
//then it deallocates the memory at "00123A" where our object was
}
Now back to std::allocator and destroy() vs deallocate()
allocator is an abstraction(interface) for memory allocation. It separates allocation from destruction, deallocation from destruction.
destroy() - "destroys" data on a memory location which makes the object not usable,but the memory is still there for use(the object can be constructed again)
deallocate() - "deallocates" the memory location where the object was, so that the storage is not usable for constructing the object on this location again. enter code here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With