Separation of C ++ memory allocation and object structure

Source: Internet
Author: User

Separation of C ++ memory allocation and object structure
In C ++, we basically use the new (delete) operator to allocate (release) memory. The new operator allocates memory for a specific type and constructs an object of this type in the newly allocated memory. The new expression automatically runs an appropriate constructor to initialize each dynamically assigned class type object. That is, the new expression allocates both memory and constructs objects. However, we will certainly encounter the following situation: Pre-allocate the memory used to create new objects, and construct each object in pre-allocated memory as needed. The reason for separating memory allocation from object construction is as follows: (1) it is a waste of constructing objects during memory allocation, and it is possible to create unused objects. (2) When pre-allocated objects are used, the used objects are likely to be re-assigned. String * pstr = new string [5]; The above example is not suitable (of course you should replace it with vector <string> ), undoubtedly, the allocated five string spaces are initialized by the string default constructor, and you must pair pstr [0... 4] assign a value again. Therefore, the distribution feature of the new operator increases the runtime overhead. In particular, some users' class types require faster object allocation. Generally, the method is to pre-allocate the memory used to create new objects and construct each new object in the pre-allocated memory. 1. Allocating original memory C ++ provides two methods to allocate and release unconstructed original memory: (1) allocator class, which provides perceptible memory allocation. This class supports abstract interfaces to allocate memory and then use this memory to save objects. (2) operator new and operator delete in the standard library, which allocate and release the original untyped memory that requires size. 1. allocator class is a template that provides typed memory allocation and Object Construction and revocation. It supports the following operations: the allocator class separates the memory allocation from the object structure. When allocator objects are allocated with memory, they are allocated with appropriate sizes and arranged to save the space of the given type of objects. The memory allocated by allocator is not constructed. The allocator users must place construct and destroy in the memory respectively. The self-growth of vector tells us that in order to achieve rapid memory allocation, the actual space allocated by vector is much more than the space currently needed. (The actual space varies with the implementation of libraries.) to illustrate the use of allocator, we can simply implement the push_back operation in STL vector. Template <class T> class VECTOR {public: VECTOR (): elements (NULL), first_free (NULL), end (NULL) {} void push_back (const T &); private: static allocator <T> alloc; void reallocate (); T * elements; T * first_free; T * end ;}; elements: points to the first element of the array; first_free: the element that points to the last actual element; end: the element that points to the array itself. The figure below may be clearer. Template <class T> void VECTOR <T>: push_back (const T & t) {if (first_free = end) // check whether there is space available {reallocate (); // allocate new space and copy existing elements} alloc. construct (first_free, t); // construct a new element + + first_free;} below is a simple implementation of reallocate (): template <class T> void VECTOR <T>: reallocate () {ptrdiff_t size = first_free-elements; ptrdiff_t newCapacity = 2 * max (size, 1); T * newElement = alloc. allocate (newCapacity); // allocate two times of memory uninitialize D_copy (elements, first_free, newElement); // copy the original memory element to the new memory for (T * p = first_free; p! = Elements;) // The original memory element calls the Destructor {alloc in reverse order. destroy (-- p);} if (elements) {alloc. deallocate (elements, end-elements); // undo the original memory space} elements = newElement; // adjust the new memory space pointer to first_free = elements + size; end = elements + newCapacity;} Description: This example is a simple description. If you are interested in vector or STL implementation, you can read the STL source code analysis book. I also learned a lot from this book. 2. When the operator new function and the operator delete function are executed, there are three steps: (1) Call the standard library function named operator new, allocate enough original untyped memory to save an object of the specified type. (2) run a constructor of this type to construct an object with the specified initialization type. (3) returns a pointer to the newly allocated and constructed object. Two steps are taken when delete sp; is executed: (1) run an appropriate destructor on the object pointed to by sp. (2) Call the standard library function named operator delete to release the memory used by the object. Operator new and operator delete functions have two overloaded versions. Each version supports related new operations: void * operator new (size_t); void * operator new [] (size_t ); void * operator delete (size_t); void * operator delete [] (size_t); Note: Although operator new and operator delete are designed for new operators, but they are also functions in the standard library and can be used to obtain unconstructed memory. Example: T * newElement = alloc. allocate (newCapacity); // allocate two times of memory T * newElement = static_cast <T *> (operator new [] (sizeof (T) * newCapacity )); the preceding two statements are equivalent, and the following two statements are also equivalent. Alloc. deallocate (elements, end-elements); // undo the original memory space operator delete [] (elements); Description: allocator class allocates typed memory, during use, you do not need to calculate the memory required in bytes, nor do you need to forcibly convert the return value of operator new. It is more secure than using operator new directly. 2. Object Construction and revocation C ++ provides different methods to construct and revoke objects in the original memory: (1) construct and destroy members of the allocator class. (2) locate the new expression. (3) directly call the destructor of the object to cancel the object. The undo object does not release the memory of the object. (4) The uninitialized_copy and uninitialized_fill algorithms construct objects. The following describes how to locate the new expression (we have seen it in other cases ). Locate the new expression to initialize an object in the allocated original memory. It does not allocate memory, accepts pointers to allocated but unconstructed memory, and initializes an object in the memory. The new expression is located in the form of new (place_address) type (initializer-list) Where place_address must be a pointer, initializer-list provides an initialization list that may be empty. Example: alloc. construct (first_free, t); new (first_free) T (t); string * sp = alloc. allocate (2); new (sp) string (B, e); Note: (1) when locating a new expression to initialize an object, you can use any constructor and create an object directly. Construct members of the allocator class always use the copy constructor. (2) For value types, directly constructing an object is no different from constructing a temporary object and copying it. The performance difference is basically meaningless. However, for some classes, it is impossible to use the copy constructor (the copy constructor may be private) or avoid this. In this case, you may consider positioning the new expression.

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.