C ++ Primer study note _ 100 _ special tools and technologies -- Optimizing memory allocation [continued 2]

Source: Internet
Author: User

C ++ Primer study note _ 100 _ special tools and technologies -- Optimizing memory allocation [continued 2]
Special tools and technologies-optimizing memory allocation [continued 2]

7. A memory distributor base class

An original memory is allocated in advance to save unconstructed objects. when creating new elements, they can be constructed in a pre-allocated object. When elements are released, instead of returning the memory to the system, place them in blocks of pre-allocated objects. This policy is often called to maintain a free list. The Free List can be implemented as a linked list of allocated but unconstructed objects.

We will define a new class named CachedObj to process the Free List. The CachedObj class can be used for classes like QueueItem that wish to optimize the allocation of their objects, instead of directly implementing their new and delete members.

The CachedObj class has a simple interface: It only allocates and manages the Free List of allocated but not constructed objects. This class defines a member operator new, returns the next element of the Free List, and deletes the element from the Free List. When the Free List is empty, operator new allocates new original memory. This class also defines operator delete, which puts the elements back into the Free List when revoking the object.

Classes that want to use a free list allocation policy for their own types will inherit the CachedObj class. through inheritance, these classes can be defined using the operator new and operator delete of the CachedObj class, and the data members required for the Free List. The CachedObj class is used as the base class, so a public virtual destructor is provided to it.

As we will see, CachedObj can only be used for types not included in the inheritance hierarchy. Unlike the new and delete operations on members, the CachedObj class cannot allocate objects of different sizes based on the actual type of objects: its free list stores a single size object. Therefore, it can only be used for classes that are not used as the base class, such as the QueueItem class.

The data member defined by the CachedObj class and inherited by its derived class is:

? The static pointer pointing to the Free List header.

? A pointer named next pointing from a CachedObj object to another CachedObj object.

The next pointer links the elements to 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 distributor but not used by the inherited type. When the object is used, the pointer is meaningless and not used; when the object is available and in the Free List, the next pointer is used to point to the next available object.

If the CachedObj class is used to optimize the allocation of the Screen class, the Screen type object (conceptual) Looks like:


1. CachedObj class

template 
 
  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
  
    alloc_mem;    static T *freeStore;    static const std::size_t chunk;};
  
 

[Description]

New and delete members remove objects from the Free List and return objects to the Free List respectively.

Static member management Free List. These member declarations are static because only one free list is maintained for all objects of the given type. The freeStore Pointer Points to the 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 the Free List. operator new uses this function to place the newly allocated object in the Free List. When deleting the object, operator delete also uses this function to return the object to the Free List.

2. Use CachedObj

When the CachedObj class is inherited, the template type used to instantiate the CachedObj class is the derived type.

To optimize the memory management of the Screen class, we declare Screen:

Class Screen: public CachedObj
 
  
{//...}; Because QueueItem is a template type, it is complicated to derive from CachedObj: template
  
   
Class QueueItem: public CachedObj <QueueItem
   
    
> {//...};
   
  
 


Our class does not need to be changed. Now the QueueItem class has automatic memory allocation. This memory allocation uses the Free List to reduce the number of allocations required when creating new Queue elements.

3. How to allocate work

Because we derive the QueueItem class from the CachedObj class, any allocation using the new expression, such as the call in Queue: push:

QueueItem
 
   *pt = new QueueItem
  
   (val); 
  
 

Assign and construct a new QueueItem object. Each expression

1) Use QueueItem : The operator new function allocates an object from the Free List.

2) For type T, use the copy constructor of the element type to construct an object in the memory.

Similarly, when you delete a QueueItem pointer like delete pt, run the QueueItem destructor to clear the object to which it points, and call the operator delete of this class, put the memory used by the element back into the Free List.

4. Define operater new

The operater new member returns an object from the Free List. If the Free List is empty, the new member must first allocate the chunk Number of memory:

template 
 
  void *CachedObj
  
   ::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
   
    ::next;    return p;}
   
  
 

The operator new function checks whether there are objects in the Free List. If not, it requests the allocator member to allocate chunk new unconstructed objects. Then, it iterates through the newly allocated objects, set the next pointer. After the add_to_freelist function is called, each object in the Free List will not be constructed except to save the next pointer of the next available object. Free List:


Operator new returns the address of the first object in the Free List, and resets the freeStore pointer to the next element in the Free List. The returned object is unconstructed. Because the new expression calls Z struct? Http://www.bkjia.com/kf/ware/vc/ "target =" _ blank "class =" keylink "> keys/zoaM8L3A + PHA + keys + Wz/cHLttTP87G + keys + PHByZSBjbGFzcz0 =" brush: java; "> template Void CachedObj : Operator delete (void * p, std: size_t) {if (p! = 0) add_to_freelist (static_cast (P ));}

It calls the add_to_freelist member to return the deleted object to the Free List.

The interesting part is forced type conversion. Operator delete is called when a dynamically assigned class type object is deleted. The Compiler sends the object address to operator delete. However, the pointer parameter type must be void *. Before calling add_to_freelist, the pointer must be forcibly converted from void * to its actual type. In this example, that type is a pointer to T, which is a pointer to an object of the CachedObj derived type.

6. add_to_freelist Member

The task of this member is to set the next pointer and update the freeStore pointer when adding the object to the Free List:

template 
 
  void CachedObj
  
   ::add_to_freelist(T *p){    p -> CachedObj
   
    ::next = freeStore;    freeStore = p;}
   
  
 

To avoid any conflicts with the Members defined in the derived class, explicitly specify that we are assigning values to the base class member next.

7. Define static data members

template 
 
   std::allocator
  
    CachedObj
   
    ::alloc_mem;template 
    
      T *CachedObj
     
      ::freeStore = 0;template 
      
        const std::size_t CachedObj
       
        ::chunk = 24; 
       
      
     
    
   
  
 

As usual, for static members of the class template, different static members are used for each type to instantiate the CachedObj class. Initialize the chunk to any value. In this example, the value is 24. Initialize the freeStore pointer to 0, indicating that the freeStore pointer is empty at the beginning. The alloc_mem member does not need to be initialized, but you must remember to define it.


// P646 exercise 18.10 after source code modification, class iStack {public: iStack (int capacity): stack (capacity), top (0) {} iStack (): top (0) {} private: vector
 
  
Stack; int top ;}; int main () {iStack * ps = new iStack (20); const iStack * ps2 = new const iStack (15 ); iStack * ps3 = new iStack [100];}
 


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.