Placement new operator in C + +

Source: Internet
Author: User

Placement new is a standard, global version of the overloaded operator new, which cannot be replaced by custom versions (unlike normal operator new and operator delete can be replaced with user-defined versions).

Its prototype is as follows:

void *operator new (size_t, void *p) throw () {return p;}

First, we distinguish the next few confusing keywords: new, operator new, placement new

Both the new and delete operators are used, and they are applied and freed from the memory in the heap, which cannot be overloaded. To implement different memory allocation behaviors, you need to overload operator new instead of new and delete.

Look at the following code:

Class MyClass {...};

MyClass * P=new MyClass;

The new here is actually performing the following 3 procedures:

1 call operator new to allocate memory;

2 Call the constructor to generate the class object;

3 returns the corresponding pointer.

operator new, like operator+, can be overloaded, but it is not possible to overload the prototype with the operator new (size_t size) in a global way, typically only in classes. If operator new is not overloaded in the class, then the call is global: operator new to complete the heap allocation. Similarly, operator new[], operator delete, operator delete[] can also be overloaded, generally you overload one of them, then it is best to load the remaining three all over again.

Placement New is an overloaded version of operator new, but we seldom use it. If you want to create an object in an already allocated memory, it is not possible to use new. This means that placement new allows you to construct a new object in an already allocated memory (stack or heap). The void*p in the prototype is actually the first address that points to an already allocated memory buffer.

We know that allocating memory using the new operator requires finding enough free space in the heap, which is slow, and there is the possibility of an exception (not enough space) to allocate memory. Placement new can solve this problem. We construct objects in a pre-prepared memory buffer, do not need to find memory, memory allocation time is constant, and do not appear in the middle of the program run out of memory exceptions. Therefore, placement new is ideal for applications that do not want to be interrupted for long periods of time.

Here's how to use it:

1. Buffer Advance allocation

You can use heap space or stack space, so there are two ways to allocate it:

Class MyClass {...};
Char *buf=new char[n*sizeof (MyClass) + sizeof (int)]; or char buf[n*sizeof (MyClass) + sizeof (int)];

2. Construction of objects

MyClass * Pclass=new (BUF) MyClass;

3. Destruction of objects

Once this object is used, you must explicitly call the class's destructor to destroy the object. However, the memory space is not freed so that other objects are constructed.

Pclass->~myclass ();

4. Release of Memory

If the buffer is in the heap, then call delete[] BUF; release the memory; if it is in the stack, then it is valid within its scope, and the memory is freed automatically by jumping out of scope.

Attention:

1) in the C + + standard, for placement operator new [] like the following description: placement operator new[] needs implementation-defined amount of Addit ional Storage to save a size of array. So we have to apply more than the size of the original object, sizeof (int) bytes to hold the number of objects, or the size of the array.

2) How to use the new in the second step is placement new, actually does not apply for memory, just call the constructor, return a pointer to the allocated memory, so the object does not need to call Delete to free space, but the destructor must be called to destroy the object.

--------------------------------------------------------------------------------------------------------------- --

To explicitly call constructors and destructors

Chatting with colleagues today, he said that STL source code useful to display call destructors. Try it for a second. It sure does.

Results:

Constructors

Destructors//This is a destructor that shows the call

Destructors//This is a destructor for the delete call

What's the use of this?

Sometimes it comes in handy to end the object's life cycle before it ends.

This is thought of:

Because I know.

New, two things are actually done, one is: Call malloc to allocate the required memory, and two: Call the constructor.

Delete, also do two things, one is: Call the destructor, and the second is: Call free memory.

So it is assumed that constructors can also be explicitly called. Made a realization.

int _tmain (int argc, _tchar* argv[]) {    myclass* Pmyclass = (myclass*) malloc (sizeof (MyClass));     Pmyclass->myclass ();    ...}

Error compiling Pmyclass->myclass ():

Error C2273: ' Function-style cast ': illegal as right side of ' operator '

God, it thinks MyClass is this type.

There are two solutions:

First: Pmyclass->myclass::myclass (); second: New (Pmyclass) MyClass ();

The second usage involves the use of C + + placement new.

The role of placement new is to create an object (call the constructor of the class) but not allocate memory, but instead create an object on the existing block of memory. For objects that need to be repeatedly created and deleted, you can reduce the performance consumption of allocating freed memory. Please refer to the placement new information.

What is the use of displaying the call constructor?

Sometimes, you might want to use malloc to allocate memory to class objects because of efficiency considerations, because malloc does not call constructors, so this time it will come in handy.

The following is also possible, although the built-in type has no constructors.

int* i = (int*) malloc (sizeof (int)); new (i) int ();

It is best to feel these strange usages when writing a code base, to use it in order to reach an eye, and not to recommend application development.

#include <iostream>usingnamespace std;class myclass{public:    MyClass ()    {        cout << Constructors "<< Endl;    }    ~myclass ()    {        cout << "destructors" << Endl;    }}; int _tmain (int argc, _tchar* argv[]) {   myclass* pmyclass =new MyClass;   Pmyclass->~myclass ();   Delete Pmyclass;}

New/delete and operator in C + + New/operator Delete

New Operator/delete operator is the new and delete operators, and operator New/operator Delete is a function.

New operator
(1) Call operator new to allocate enough space and call the constructor of the related object
(2) can not be overloaded

operator NEW
(1) Only the required space is allocated, and the constructor of the related object is not called. When the required allocated space is not met, the
-If there is new_handler, call New_handler, otherwise
-If no exception is required (expressed in the nothrow parameter), the BAD_ALLOC exception is executed, otherwise
--Return 0
(2) can be overloaded
(3) When overloading, the return type must be declared as void*
(4) When overloading, the first parameter type must be the size (in bytes) of the allocation space for the expression requirement, type size_t
(5) When overloading, can take other parameters

Delete is similar to delete operator

#include <iostream> #include <string>using namespace Std;class x{public:    X () {cout<< " Constructor of X "<<endl; }    ~x () {cout<< "destructor of X" <<ENDL;}    void* operator new (size_t size,string str)    {        cout<< "operator new size" <<size<< "with string" <<str<<endl;        Return:: operator new (size);    }    void operator Delete (void* pointee)    {        cout<< "operator delete" <<endl;        :: operator Delete ( pointee);    } Private:    int num;}; int main () {    x *px = new ("A new Class") x;    Delete px;    return 0;}

x* px = new X; New in the line code is new operator, which invokes operator new in class X, allocates space for the object of the class, and then invokes the constructor of the current instance.
Delete px; The delete in the line code is delete operator, which invokes the destructor for the instance, and then calls the operator delete in class X to free up the space occupied by the instance.

The behavior of new operator and delete operator is not and should not be changed, which is a commitment made by the C + + standard. And operator new and operator delete and the C language of malloc and free correspond, only responsible for allocating and freeing space. However, the space allocated using operator new must be freed using operator delete, not free, because they are not registered in the same way as memory usage. The reverse is also the same. You can reload operator new and operator delete to implement different requirements for memory management, but you cannot overload the new operator or delete operator to change their behavior.

Why is it necessary to write your own operator new and operator delete?
The answer is usually: for efficiency. The default operator new and operator Delete are very versatile, and this flexibility makes it possible to further improve its performance in certain situations. This is especially true in applications that need to dynamically allocate large but small objects. Refer to the second chapter, "Effective C + +" for memory management.

The meaning of Placement new

Placement new is a standard, global version of the overloaded operator new, which cannot be replaced by custom versions (unlike the normal version of operator new AND operator delete can be replaced).

void *operator new (size_t, void * p) throw () {return p;}

Placement new's execution ignores the size_t parameter, returning only the second argument. The result is that the user is allowed to put an object in a specific place, reaching the effect of invoking the constructor. Unlike other normal new, it has another parameter in parentheses. Like what:

Widget * p = new Widget; Ordinary New

PI = new (ptr) int;     PI = new (ptr) int; Placement NEW

The parameter ptr in parentheses is a pointer to a memory buffer, and placement new will allocate an object on the buffer. The return value of Placement new is the address of the constructed object (such as the pass parameter in parentheses). Placement New is primarily intended for applications where time is very high, because the time allotted for these programs is deterministic, for long-running programs that are not interrupted, and for executing a garbage collector (garbage collector).

New, operator new and placement new differences

(1) NEW: cannot be overloaded, its behavior is always consistent. It first calls operator new to allocate memory, and then calls the constructor to initialize that piece of memory.

The new operator executes the procedure:
1. Call operator new to allocate memory;
2. Call the constructor to generate the class object;
3. Return the appropriate pointer.

(2) operator NEW: To implement different memory allocation behavior, operator new should be overloaded instead of new.

operator new is like Operator +, which can be overloaded. If operator new is not overloaded in the class, then the call is global: operator new to complete the heap allocation. Similarly, operator new[], operator delete, operator delete[] can also be overloaded.

(3) Placement NEW: Just one version of operator new overload. It does not allocate memory, but returns a pointer to a memory that has already been allocated. Therefore, you cannot delete it, but you need to call the object's destructor.

If you want to create an object in an already allocated memory, it won't work when you use new. In other words, placement new allows you to construct a new object in an already allocated memory (stack or heap). The void* p in the prototype is actually the first address that points to an already allocated memory buffer.

Reasons for the existence of Placement new

1. Using placement new to solve the problem of buffer

Problem Description: When you allocate an array buffer with new, the execution is inefficient because the default constructor is called. If there is no default constructor, a compile-time error occurs. If you want to create an object on pre-allocated memory, it won't work with the default new operator. To solve this problem, you can use the placement new construct. It allows you to construct a new object onto the pre-allocated memory.

2. Increasing the time-space efficiency problem

allocating memory using the new operator requires finding enough free space in the heap, which is obviously slow, and there is the possibility of an exception (not enough space) to allocate memory. Placement new can solve this problem. We construct objects in a pre-prepared memory buffer, do not need to find memory, memory allocation time is constant, and do not appear in the middle of the program run out of memory exceptions. Therefore, placement new is ideal for applications that do not want to be interrupted for long periods of time.

Placement New Use steps

In many cases, the use of placement new differs from other common new. This provides the steps to use it.

First step cache advance allocation

There are three ways of doing this:

1. In order to ensure that the memory alignment of the buffers used by placement new are properly prepared, the normal new is used to allocate it: allocate on the heap
Class Task;
char * buff = new [sizeof (Task)]; Allocating memory
(Note that auto or static memory is not all correctly arranged for each object type, so you will not be able to use them with placement new.) )

2. Allocating on the stack
Class Task;
Char buf[n*sizeof (Task)]; Allocating memory

3. There is also a way to use the address directly. (Must be a meaningful address)
void* buf = reinterpret_cast<void*> (0xf00f);

Second step: Assignment of objects

In the buffer just allocated, call placement new to construct an object.
Task *ptask = new (BUF) task

Step Three: Use

Use assigned objects in the normal way:

Ptask->memberfunction ();

Ptask-> member;

//...

Fourth step: object's destruction

Once you have finished using this object, you must call its destructor to destroy it. Call the destructor in the following way:
Ptask->~task (); Call an external destructor

Fifth Step: Release

You can reuse the cache and assign it a new object (Repeat step 2,3,4) If you are not going to use this cache again, you can release it like this: delete [] buf;

Skipping any step can lead to run-time crashes, memory leaks, and other unexpected situations. If you do need to use placement new, follow these steps carefully.

#include <iostream>using namespace Std;class x{public:    x () {cout<< "constructor of X" <<endl;}    ~x () {cout<< "destructor of X" <<ENDL;}    void Setnum (int n)    {        num = n;    }    int Getnum ()    {        return num;    } Private:    int num;}; int main () {    char* buf = new char[sizeof (X)];    X *px = new (BUF) x;    Px->setnum (ten);    Cout<<px->getnum () <<endl;    Px->~x ();    delete []buf;    return 0;}

http://blog.csdn.net/w616589292/article/details/51044640

Placement new operator in C + +

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.