C + + Primer Learning notes _100_ special tools and techniques-Optimizing memory allocation [Cont. 2]

Source: Internet
Author: User

Special tools and technologies--Optimize memory allocation[continued2]

Seven.a memory allocator base class

Pre-assigned piece The raw memory is used to hold the objects that are not constructed, and when the new elements are created, they can be constructed in a pre-allocated object, and when the elements are released, they are placed back into the pre-allocated blocks instead of actually returning the memory to the system . This strategy is often referred to as maintaining a free list. You can implement the free list as a linked list of objects that have been allocated but not constructed.

we will define a  cachedobj  CACHEDOBJ  do not directly implement their own  NEW  and   DELETE  member.  

cachedobj  operator new OPERATOR NEW  operator delete when the object is undone.

the class that you want to use a free list to assign policies for your type inherits   CACHEDOBJ  OPERATOR NEW  and   OPERATOR DELETE  definition, as well as the data members required to represent the free list. As intended to be  , CACHEDOBJ  PUBLIC  virtual destructor.  

As we will see,cachedobj can only be used for types that are not included in the inheritance hierarchy. Unlike the member new and Delete operations, thecachedobj Class has no way to allocate objects of different sizes based on the actual type of the object: its free list holds objects of a single size. Therefore, it can only be used for classes that do not use the base class, such as the queueitem class.

The data members defined by the Cachedobj class and inherited by its derived classes are:

? that points to the Free list table header. Static pointer.

? name is Next , from a Cachedobj object points to another Cachedobj  the pointer to the object.

the next pointer links the elements into the free list. each type derived from the Cachedobj class contains its own type-specific data, plus a Pointer inherited from the Cachedobj base class. Each object has an extra pointer that is used by the memory allocator but is not used by the inherited type, when the object is used, the pointer is meaningless and unused; When the object is available and in the free list, it uses the next Pointer to point to the next available object.

If you use the cachedobj class to optimize The allocation of the screen class, The object of screen type (conceptually) looks As shown :


1.CACHEDOBJ class

Template <typename t>class cachedobj{public:    void *operator New (std::size_t);    void operator delete (void *,std::size_t);    Virtual ~cachedobj () {}protected:    t *next;private:    static void Add_to_freelist (T *);    Static std::allocator<t> Alloc_mem;    Static T *freestore;    static const std::size_t Chunk;};

[ description ]

new  and   delete  members take objects from a free list and .  

Static members manage free lists. These members are declared staticbecause only a free list is maintained for all objects of a given type. Freestore the pointer points to the table header of the free list. A member named Chunk Specifies the number of objects that will be allocated whenever the free list is empty. finally ,the Add_to_freelist function places the object in a free list,andoperator New uses this function to place the newly allocated object in the free list, deleting the object, operator Delete also uses this function to put the object back into the free list.

2. Using cachedobj

When inheriting the cachedobj class, the template type used to instantiate The Cachedobj class will be the derived type itself.

To optimize the memory management of the screen class, we declare screen as:

Class Screen:public cachedobj<screen>{    //...}; Because Queueitem is a template type, deriving it from Cachedobj is somewhat complex: template <typename t>class queueitem:public cachedobj< queueitem<t > >{    //...};


Our class doesn't need any other changes. Now that the Queueitem class has automatic memory allocation, this memory allocation uses a free list to reduce The number of allocations required to create a new Queue element.

3. How to assign work

Because we derive the Queueitem class from the cachedobj class , any allocations that use the new expression, such as Queue::p ush: call in :


Allocates and constructs a new Queueitem object. Per-expression

1) Use the queueitem<t>::operator new function to assign an object from the free list.

2) Use the copy constructor of the element type for type T to construct an object in that memory.

Similarly, when deleting a queueitem pointer like delete pt , run the queueitem destructor to clear the object that points to, and call the class's operator Delete , put the memory used by the element back into the free list.

4. Definition operater New

operater new  member returns an object from the free list If the free list is empty ,new must first be assigned chunk Span style= "font-family: the song Body;" > number of memory :

Template <typename t>void *cachedobj<t>::operator new (std::size_t sz) {    if (sz = = sizeof (T))        throw Std::runtime_error        ("Cacheobj:wrong size object in operator new");    if (!freestore)    {        T *array = alloc_mem.allocator (chunk);        for (size_t i = 0; I! = chunk; ++i)        {            add_to_freelist (&array[i]);}    }    T *p = Freestore;    Freestore = Freestore-cachedobj<t>::next;    return p;}

The operator new function checks whether there are objects in the free list, and if not, it requests the allocator member to assign chunk A new, non-constructed object , and then it iterates through the newly allocated object, setting the next pointer. once the add_to_freelist function is called, each object on the free list will not be constructed except that it will save the address of the next available object , the next pointer. Free list :


operator New returns the address of the first object on the free list , and resets the freestore Pointer to the next element of the free list, under the guarantee that the available objects can be assigned. The object being returned is not constructed . Because operator newis called from the new expression , the new expression is responsible for constructing the object .

5. Define operater Delete

Operator delete member is only responsible for managing memory, the object itself has been cleared in the destructor, andthedelete expression is called operator delete The destructor was called before. operator Delete member is simple:

Template <typename t>void cachedobj<t>::operator Delete (void *p,std::size_t) {    if (P! = 0)        add_to_ Freelist (Static_cast<t*> (P));}

It calls the add_to_freelist member to put the deleted object back into the free list.

The interesting part is the coercion of type conversions. When you delete a dynamically allocated class type Object, the operator deleteis called, and the compiler passes the address of the object to operator delete. However, the parameter type of the pointer must be void*, and before calling add_to_freelist , the pointer must be from the void*  Cast to its actual type, in this case, the type is a pointer to T , which is a pointer to an object of cachedobj derived type.

6.add_to_freelist Members

The task of this member is to set the next pointer and update the freestore pointer when the object is added to the free list :

Template <typename t>void cachedobj<t>::add_to_freelist (T *p) {    P-, Cachedobj<t>::next = Freestore;    Freestore = P;}

To avoid any possible conflicts with the members defined in the derived class, explicitly specify that we are assigning a value to the base class member next .

7. Defining static data members

Template <typename t> std::allocator<t> cachedobj<t>::alloc_mem;template <typename T> T * Cachedobj<t>::freestore = 0;template <typename t> const std::size_t cachedobj<t>::chunk = 24;  

As usual, for static members of class templates, each type uses a different static member to instantiate the Cachedobj class. Initialize the chunk to any value in this case . initializes the freestore pointer to 0, indicating that the free list starts empty. The ALLOC_MEM member does not need to be initialized, but must remember to define it .


P646 Exercise 18.10 Source code modified Class Istack{public:    istack (int capacity): stack (capacity), top (0) {}    Istack (): Top (0) {} Private:    vector<int> stack;    int top;}; int main () {    Istack *ps = new Istack;    Const Istack *PS2 = new Const istack (15);    


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.