More effective C + +----(8) Understand the various meanings of new and delete

Source: Internet
Author: User

Item M8: Understanding the various meanings of new and delete
People sometimes seem to like to deliberately make the C + + language's terminology difficult to understand. For example new operator(new operator) and New OperationThe difference between (operator new).
for knowledge of the new operator and the new operation, refer to < http://blog.csdn.net/qianqin_2014/article/details/51320775>
When you write such a code:
String *ps = new String ("Memory Management");

You New is the new operator used。 This operator is like sizeof is a language built -in, you can't change the meaning of it, its function is always the same. The function it is to complete is divided into two parts.The first part is to allocate enough memory to accommodate the object of the desired type. The second part is that it calls the constructor to initialize the in-memory object. The new operator always does both things, and you can't change its behavior in any way. ( The C + + Primer points out that new has to do three things!!!
What you can change is how to allocate memory for an object.。The new operator calls a function to complete the required memory allocation, and you can override or reload the function to change its behavior. The name of the function called by the new operator for allocating memory is operator new.
The function operator new usually declares this:
void * operator new (size_t size);

The return value type is void*, because this function returns an unprocessed (raw) pointer, uninitialized memory。 (If you like, you can write a operator new function that initializes memory to store some values before returning a pointer, but generally does not.) ) parameter size_t determine how much memory is allocatedyou can add additional arguments to the overloaded function operator new, but the first parameter type must be size_t. (For more information about operator new, see effective C + + clause 8 to clause 10.) )
You don't normally call operator new directly, but once you do, you can invoke it like any other function:
void *rawmemory = operator new (sizeof (string));

The operator operator new returns a pointer to a piece of memory sufficient to hold a string object.
Just like malloc, the responsibility of operator new is simply to allocate memory。 It has no knowledge of the constructor function. Operator new is aware of memory allocations. passing an unhandled pointer returned by operator new to an object is the work of the new operator。 When your compiler encounters such a statement:
String *ps = new String ("Memory Management");

The code it generates is more or less similar to the following code (see effective C + + clause 8 and clause 10 for more details, as well as the comments in my article counting object. ):
void *memory =//Get unprocessed memory operator new (sizeof (string)); Call string::string for string object ("Memory Management")//Initialize on *memory; The object in memory string *ps =//Is the PS pointer pointing to static_cast<string*> (memory); The new object

Note that the second step contains the call to the constructor, and you being a programmer is forbidden to do so. Your compiler doesn't have this constraint., it can do everything it wants to do. So if you want to build a heap object you have to use the new operator and you cannot directly invoke the constructor to initialize the object.
placement NewSometimes you do want to call the constructor directly. It makes no sense to call a constructor on an existing object, because the constructor is used to initialize the object, and an object can be initialized only once given its initial value. but sometimes you have some (raw) memory that has already been allocated but not processed, and you need to construct an object in these memory. You can use a special operator new, which is called placement new.
The following example is how placement new is used, considering:
Class Widget {public:  widget (int widgetsize);  ...}; Widget * Constructwidgetinbuffer (void *buffer,                                 int widgetsize) {  return new (buffer) widget (widgetsize);}

This function returns a pointer to a Widget object that is allocated in the buffer that is forwarded to the function. When the program uses shared memory or memory-mapped I/OThis function may be useful, because in such a program the object must be placed in a determine whether an address or a piece is assigned by routineIn memory. (see article M4, a different example of how to use placement new.) )
Inside the Constructwidgetinbuffer, the returned expression is:
New (buffer) Widget (widgetsize)

This may seem strange at first, but it is a use of the new operator and requires an additional variable (buffer) (see positioning the new expression), when the new operator implicitly calls the operator new function, pass this variable to it. The called operator new function must also accept the void* pointer parameter, in addition to the mandatory parameter size_t, to the memory space occupied by the construction object. This operator new is placement new,It looks like this:
void * operator new (size_t, void *location) {  return location;}
(the above function cannot be overloaded)
This may be easier than you expect, but that's what placement new needs to do. after all, the purpose of operator new is to allocate memory for an object and then return a pointer to that memory. in the case of placement new, the caller has obtained a pointer to memory because the caller knows where the object should be placed. What placement new has to do is return the pointer to it. the unused (but mandatory) parameter size_t does not have a name to prevent the compiler from issuing a warning that it is not being used;See clause M6. Placement new is part of the standard C + + library (see effective C + + clause 49). in order to use placement new, you must use the statement # include <new> (or if your compiler does not yet support this new style header file name (see also effective C + + terms),<new.h>).
Let's come back from placement new for a moment and see Relationship of new operator (new operator) to operator new (1) you want to build an object on the heap, you should use the new operator. It allocates both memory and calls constructors for objects. (2)If you just want to allocate memory, you should call the operator new function; it does not call the constructor. (3) If you want to customize your memory allocation process when the heap object is built, you should write your own operator new function, then use the new operator, and the new operator will call your custom operator new. (4) If you want to create an object in a piece of memory that has been given a pointer, you should use placement new.
(see effective C + + clause 7 and my article counting objects for more different views of new and delete.) )

deletion and Memory deallocation
To avoid memory leaks, each dynamic memory allocation must correspond to a deallocation equivalent to the opposite. The relationship between the function operator delete and the delete operator is the same as the relationship of operator new with the new operator. When you see the code:
for the memory mechanism of allocator, refer to
String *ps;...delete PS; Using the delete operator

Your compiler generates code to deconstruct the object and release the memory that the object occupies.
Operator Delete is used to free memory, which is declared like this:
void operator delete (void *memorytobedeallocated);

So
Delete PS;  Using the delete operator

Causes the compiler to generate code similar to this:

Ps->~string ();                      Call the object ' s dtoroperator Delete (PS);                DEALLOCATE the memory                                    //the object occupied

This has an implied meaning that If you only want to handle uninitialized memory, you should bypass the new and delete operators, and call operator new to get memory and operator delete to free up memory to the system:
void *buffer =                      //Allocate sufficient operator new (50*sizeof (char));      Memory to hold 50 char                                 //No call constructor ... operator delete (buffer);              Free memory                                 //no destructor called
(because there is no object, how can we destroy the object ...)
This is equivalent to calling malloc and free in C.
If you are building an object in memory with placement new, you should avoid using the delete operator in that memory. Because the delete operator calls operator delete to free memory, but the memory that contains the object is not originally allocated by operator new, placement new simply returns the pointer that is forwarded to it. who knows where this pointer comes from? Instead, you should explicitly call the object's destructor to remove the effect of the constructor:
The function that allocates and frees memory in shared memory is void * mallocshared (size_t size), void freeshared (void *memory), void *sharedmemory = Mallocshared ( sizeof (Widget)); Widget *PW =                                   //As shown above,  constructwidgetinbuffer (Sharedmemory, ten);   Use                                               //placement New ... delete pw;            The results are not sure! Shared memory comes from                      //mallocshared, not operator Newpw->~widget ();        That's right. Deconstruct the widget that the PW points to,                      //But does not release                      //contains the widget's memory freeshared (PW);       That's right. Releases the shared memory that PW points to                      //But does not call the destructor

As shown in the example above, if the raw memory passed to placement new is allocated dynamically (through some infrequently used methods), you must release it if you want to avoid a memory leak. (See my article counting objects for comments on placement Delete.) )
arraysEverything went well so far, but it had to go on. All we've tested so far is to build one object at a time. How do I allocate arrays? What's going to happen?
String *ps = new STRING[10];          Allocate an array of                                //objects

The new operator is still used, but the behavior of the new operator is slightly different from the creation of a single object when an array is created. The first is that memory is no longer allocated with operator new, instead of an equivalent array allocation function called operator new[] (often referred to as array new). It can be overloaded like operator new. This allows you to control the memory allocation of the array as if you were able to control the memory allocations of individual objects (but there are some restrictive descriptions, see effective C + + clause 8).
(operator new[] is a relatively new thing for C + +, so your compiler might not support it. If it is not supported, regardless of the object type in the array, global operator new will be used to allocate memory for each array. Customizing array memory allocations under such a compiler is difficult because it requires overriding the global operator new. This is not an easy task to accept. By default, all dynamic memory allocations in the global operator new handler, so any changes to its behavior will have deep and pervasive implications. and the global operator new has a normal signature (normal signature) (also on a single parameter size_t, see effective C + + clause 9), so if you decide to declare it in your own way, You immediately make your program incompatible with other libraries (see clause M27) based on these considerations, it is not a reasonable design to set up an array of custom memory management in a compiler that lacks operator new[] support. )
The second difference is the number of constructors that the new operator calls. For arrays, the constructors for each object in the array must be called:
String *ps =               //call operator new[] for 10 new string[10];            The string object allocates memory,                           //And then calls the                           //String object's default constructor on each array element.

Similarly, when the delete operator is used for an array, it calls the destructor for each array element and then calls operator delete to free up memory.
Just as you can replace or reload operator delete, you also replace or reload operator delete[]. There are some limitations on the methods that they overload. Please refer to the excellent C + + textbook.
The new and delete operators are built-in, and their behavior is not controlled by you, and the memory allocation and deallocation functions they call can be controlled. When you want to customize the behavior of the new and delete operators, keep in mind that you can't really do that. You can only change the way they are used to accomplish their functions, and the functions they perform are fixed by the language and cannot be changed. (Can modify how they does what they does, but what they does is fixed by the language)


More effective C + +----(8) Understand the various meanings of new and delete

Related Article

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.