First, new operator (new operator)
People sometimes seem to like to deliberately make the C + + language's terminology difficult to understand. For example, the difference between the new operator (new operator) and operator new.
When you write such a code:
String *ps = new String ("Memory Management");
The new you are using isnew operator。 This operator, like sizeof, is a language built-in, and you can't change its meaning, it always functions 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 summary is thatThe new operator does two things, allocating memory + calling constructor initialization. You can't change the way it behaves. )
Second, operator new
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 to 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 determines how much memory is allocated.you 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, operator New's responsibility 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. ):
<pre name = "code" class = "cpp"> void * memory = operator new (sizeof (string)); // Get unprocessed memory as a String object
call string :: string ("Memory Management")
on * memory; // objects in memory
string * ps = static_cast <string *> (memory); // make the ps pointer point to the new object
Note that the second step contains the constructor call, which you do as a programmer is forbidden to do. Your compiler does not 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. (Summary: operator new is a function for allocating memory, called for the new operator, and can be overloaded (with restrictions))
Third, placement new
Sometimes 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. This function may be useful when a program uses shared memory or memory-mapped I/O, because in such a program the object must be placed on a certain address or in memory allocated by the routine. (see article 4, a different example of how to use placement new.) )
In Constructwidgetinbuffer, the returned expression is: New (buffer) Widget (widgetsize)
This may seem strange at first, but it is a use of the new operator, which requires an extra variable (buffer), which is passed to the new operator when it implicitly calls the operator new function. 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 constructed object. This operator new is placement new, which looks like this:
void * operator new(size_t, void *location)
{
return location;
}
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 has no name to prevent the compiler from issuing a warning that it is not being used; see clause 6. Placement new is part of the standard C + + library. 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).
( Summary: Placement New is a special operator new, used for a piece of raw memory that has been allocated but not processed or initialized )
Iv. Summary
Let's come back from placement new for a moment and see the new operator (new operator) with operator New, (the new operator calls operator new)
You want to build an object on the heap, you should use the new operator. It allocates both memory and calls constructors for objects.
If you just want to allocate memory, you should call the operator new function; it does not call the constructor.
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.
If you want to create an object in a piece of memory that has been given a pointer, you should use placement new.
V. 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:
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);
Therefore, delete PS; Causes the compiler to generate code similar to this:
Ps->~string (); Call the object ' s dtoroperator Delete (PS); Deallocate the memory the object occupied
One implication of this is 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 = operator new (50 * sizeof (char)); // allocate enough memory to hold 50 chars
// did not call the constructor
...
operator delete (buffer); // release memory
// did not call the destructor
This is equivalent to calling malloc and free in C.
How is the object created by 2.placement new released?
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:
// Functions that allocate and release memory in shared memory void * mallocShared (size_t size);
void freeShared (void * memory);
void * sharedMemory = mallocShared (sizeof (Widget));
Widget * pw = // As shown above,
constructWidgetInBuffer (sharedMemory, 10); // use
// placement new
...
delete pw; // The result is uncertain! The shared memory comes from
// mallocShared, not operator new
pw-> ~ Widget (); // Correct. Destructs the widget pointed to by pw,
// but not released
// Contains the memory of the Widget
freeShared (pw); // Correct. Release the shared memory pointed to by pw
// but the destructor is not called
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.) )
Six, array
Everything 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 based on these considerations, the array custom memory management is not a reasonable design 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 = new string [10]; // call operator new [] to allocate memory for 10 string objects,
// Then call the default constructor of the string object for 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. (buxizhizhou530 Note: This should be operator delete[]
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.
(Summary: Array, two different points, one-time call operator new[] function, the second is the new operator called the number of constructors is different. )
Vii. Summary
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)
Reference: Delete in C + +, new and new [], delete[] operator insider
This article most of the content from the above blog, unfortunately this blog is reproduced, did not find the original source. This article is based on the above blog content, plus their own understanding, has been re-typesetting, color labeling, related changes, and their own summary.
If wrong, welcome to Exchange ~
Related:
Additional additions to new, operator new, and placement new in C + +
Placement new operator in C + + (classic), can be viewed slightly
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Inside of the new operator in C + +: new operator, operator new, placement new