简体   繁体   English

std :: allocator中“destroy”“析构函数”“deallocate”之间的区别?

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

In C++ std::allocator , there are three methods relating to a common concept: 在C ++ std::allocator ,有三种与常见概念相关的方法:

  • 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? destroy用于调用对象上的析构函数,这里的“对象”是什么意思?

Thank you again! 再次感谢你!

Just the brief descriptions from the cppreference.com documentation explain the differences very clearly for me 只是cppreference.com文档中的简短描述对我来说非常清楚地解释了这些差异

在此输入图像描述

"1. What does destructor do? The documentation didn't talk about whether the memory will be released automatically when the destructor is called" “1.析构函数做什么?文档没有讨论在调用析构函数时是否会自动释放内存”

Any memory occupied by the std::allocator instance will be released as usual. std::allocator实例占用的任何内存都将照常释放。

"2. The destroy is used to call the destructor on a object, what does the "object" here means?" “2. destroy用于在对象上调用析构函数,这里的”对象“是什么意思?”

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 调用p指向的对象的析构函数
1) Calls ((T*)p)->~T() 1)调用((T*)p)->~T()
2) Calls p->~U() 2)调用p->~U()

Object in this context means an object of type T managed by the std::allocator instance. 在此上下文中意味着对象类型的对象T由被管理std::allocator实例。

The answer to your question lies in the relationship between the delete operation and the object destructor. 您的问题的答案在于删除操作和对象析构函数之间的关系。

deallocate(pointer p,size_type size) deallocate(指针p,size_type大小)

- 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) 破坏(指针p)

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

About destructors 关于析构函数

  • The explicit call of a destructor is not implicitly calling delete on the object which called the destructor. 析构函数的显式调用不会在调用析构函数的对象上隐式调用delete。
  • note: ~MyClass(){ delete this; 注意:~MyClass(){删除这个; } is not an exception because it will generate an acces violation. }不是例外,因为它会生成访问冲突。

Why does it makes sense to call the destructor without using delete? 为什么在不使用delete的情况下调用析构函数是有意义的?

  • a dinamically allocated object could have pointers to allocated objects as member variables. 一个dinamically分配的对象可以指向分配的对象作为成员变量。 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. 如果你想释放那个内存而不删除保存指针的原始对象,你可以调用overriden析构函数,因为默认的不会那样做。

    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){ void set_second(const U&val){\n\n
      second_pointer=new U(val); 
    \n\n } }\n\n}; };\n\nvoid some_function(void){ void some_function(void){\n\n MyClass *object; MyClass *对象;\n\n object=new MyClass();//for example:the allocated object is at memory location 00123A object = new MyClass(); //例如:分配的对象位于内存位置00123A\n\n//lets say that after some time you dont need the memory for "first_pointer" and //让我们说,经过一段时间你不需要内存“first_pointer”和\n//"second_pointer" but you want to keep the memory for "object". //“second_pointer”但你想保留“对象”的内存。\n//so we call the destructor. //所以我们称之为析构函数。\n\n object->~MyClass();//memory at addres 00123A is still reserved for our object object-> ~MyClass(); // addres 00123A的内存仍然保留给我们的对象\n //but the first_pointer and second_pointer locations //但是first_pointer和second_pointer位置 \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 object-> set_first(T(...))//参数依赖于定义的构造函数 \n object->set_second(U(...)) //for T and U. Doesn't really matter in this example object-> set_second(U(...))//对于T和U.在这个例子中并不重要\n\n//after some time we dont need the object and it's parts at all //过了一段时间后,我们根本不需要物体,而是它的零件\n//so we call delete on the object //所以我们在对象上调用delete\n\ndelete object; 删除对象; //calls our destructor to release the memory pointed to //调用析构函数释放指向的内存 \n //by first_pointer and second_pointer. // by first_pointer和second_pointer。 \n //then it deallocates the memory at "00123A" where our object was //然后它在我们的对象所在的“00123A”处释放内存 \n\n\n} } \n\n

    Now back to std::allocator and destroy() vs deallocate() 现在回到std :: allocator和destroy()vs deallocate()

    allocator is an abstraction(interface) for memory allocation. allocator是内存分配的抽象(接口)。 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) destroy() - “破坏”内存位置上的数据,使对象无法使用,但内存仍在使用(可以再次构造对象)

    deallocate() - "deallocates" the memory location where the object was, so that the storage is not usable for constructing the object on this location again. deallocate() - “释放”对象所在的内存位置,以便存储不再可用于再次构建此位置上的对象。 enter code here 在此处输入代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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