简体   繁体   中英

Difference between “destroy” “destructor” “deallocate” in std::allocator?

In C++ std::allocator , there are three methods relating to a common concept:

  • deallocate
  • destroy
  • destructor

I want to know:

  1. How are they different from each other from the memory management perspective?
  2. when should I use this but not that?

Thank you!


Edit: More specific doubts:

I am sorry to generalize it at first, here are some points I don't understand.

  1. What does destructor do? The documentation didn't talk about whether the memory will be released automatically when the destructor is called
  2. The destroy is used to call the destructor on a object, what does the "object" here means?

Thank you again!

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) Calls p->~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.

- 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

- calls only the destructor  ((T*)p)->~T()
- the memory at addres p will not be freed/deallocated

  • The explicit call of a destructor is not implicitly calling delete on the object which called the destructor.
  • note: ~MyClass(){ delete this; } is not an exception because it will generate an acces violation.

  • 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); 
    \n\n } \n\n void set_second(const U& val){ \n\n
      second_pointer=new U(val); 
    \n\n } \n\n}; \n\nvoid some_function(void){ \n\n MyClass *object; \n\n object=new MyClass();//for example:the allocated object is at memory location 00123A \n\n//lets say that after some time you dont need the memory for "first_pointer" and \n//"second_pointer" but you want to keep the memory for "object". \n//so we call the destructor. \n\n object->~MyClass();//memory at addres 00123A is still reserved for our object \n //but the first_pointer and second_pointer locations \n //are deallocated. \n\n\n\n //then lets say that after some time we need to set the member variables \n object->set_first(T(...)) //arguments depend on the defined constructors \n object->set_second(U(...)) //for T and U. Doesn't really matter in this example \n\n//after some time we dont need the object and it's parts at all \n//so we call delete on the object \n\ndelete object; //calls our destructor to release the memory pointed to \n //by first_pointer and second_pointer. \n //then it deallocates the memory at "00123A" where our object was \n\n\n} \n\n

    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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM