As we can see, they differ only when there is no free chunk in the list of memory blocks. In this scenario, it allocates a new memory block, merges its free list to pool's free list, the difference between these two methods is that boost::pool<>::ordered_malloc preserves order while merging the free lists.Above is for question 1.So, why does the order matter?! It seems the memory pool works perfectly with the unordered chunks!First, if we want to find a contiguous sequence of n chunks, the ordered free list would make it easier. Second, Let's have a look at the derived class of boost::pool: boost::object_pool, it provides automatic destruction of non-deallocated objects on destruction of the object_pool object while you can also destroy the object manually, for example:class X { … }; void func() { boost::object_pool<X> alloc; X* obj1 = alloc.construct(); X* obj2 = alloc.construct(); alloc.destroy(obj2); }上面的代码还可以,没有内存泄漏或重复删除! boost::object_pool如何做到这一点?让我们找到boost::object_pool的析构函数的实现(我的机器上提升了1.48):the code above is OK, no memory leak or double delete! How does boost::object_pool do this magic? Let's find the implementation of destructor of boost::object_pool(I have boost 1.48 on my machine):template <typename T, typename UserAllocator>object_pool<T, UserAllocator>::~object_pool(){#ifndef BOOST_POOL_VALGRIND // handle trivial case of invalid list. if (!this->list.valid()) return; details::PODptr<size_type> iter = this->list; details::PODptr<size_type> next = iter; // Start 'freed_iter' at beginning of free list void * freed_iter = this->first; const size_type partition_size = this->alloc_size(); do { // increment next next = next.next(); // delete all contained objects that aren't freed. // Iterate 'i' through all chunks in the memory block. for (char * i = iter.begin(); i != iter.end(); i += partition_size) { // If this chunk is free, if (i == freed_iter) { // Increment freed_iter to point to next in free list. freed_iter = nextof(freed_iter); // Continue searching chunks in the memory block. continue; } // This chunk is not free (allocated), so call its destructor, static_cast<T *>(static_cast<void *>(i))->~T(); // and continue searching chunks in the memory block. } // free storage. (UserAllocator::free)(iter.begin()); // increment iter. iter = next; } while (iter.valid()); // Make the block list empty so that the inherited destructor doesn't try to // free it again. this->list.invalidate();#else // destruct all used elements: for(std::set<void*>::iterator pos = this->used_list.begin(); pos != this->used_list.end(); ++pos) { static_cast<T*>(*pos)->~T(); } // base class will actually free the memory...#endif}它遍历内存块列表中的所有块(boost::pool<>的数据成员list,保存从系统分配的所有内存块的位置和大小),以查找其中是否还有块在空闲列表中显示,如果没有,则调用对象的析构函数,然后释放内存.因此,这有点像是两个集合的交集,就像 std :: set_intersection()做!如果列表已排序,则这样做会更快.实际上,在boost::object_pool<>中需要顺序,公共成员函数:boost::object_pool<>::malloc()和boost::object_pool<>::free()分别分别调用boost::pool<>::ordered_malloc()和boost::pool<>::ordered_free():it goes through all the chunks in the list of memory blocks(list, the data member of boost::pool<>, holds the locations and sizes of all memory blocks allocated from the system) to find whether any chunk in it also shows in the free list, if not, calls the destructor of the object, then free the memory. So it's kind of getting the intersection of two sets, just as std::set_intersection() does! If the list is sorted, it would be much faster to do that. Actually in the boost::object_pool<>, the order is required, the public member functions: boost::object_pool<>::malloc() and boost::object_pool<>::free() just call the boost::pool<>::ordered_malloc() and boost::pool<>::ordered_free() respectively:element_type * malloc BOOST_PREVENT_MACRO_SUBSTITUTION(){ //! Allocates memory that can hold one object of type ElementType. //! //! If out of memory, returns 0. //! //! Amortized O(1). return static_cast<element_type *>(store().ordered_malloc());}void free BOOST_PREVENT_MACRO_SUBSTITUTION(element_type * const chunk){ //! De-Allocates memory that holds a chunk of type ElementType. //! //! Note that p may not be 0.\n //! //! Note that the destructor for p is not called. O(N). store().ordered_free(chunk);}对于问题2:在大多数情况下,您无需使用boost::pool<>::ordered_malloc.So for the queston 2: You needn't use boost::pool<>::ordered_malloc in most situations. 这篇关于boost :: pool&lt;&gt; :: malloc和boost :: pool&lt;&gt; :: ordered_malloc有什么区别,什么时候应该使用boost :: pool&lt;&gt; :: ordered_malloc?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-04 18:28