New and delete learning Summary

Source: Internet
Author: User

New and delete are particularly important in C ++. Here we will briefly summarize the meanings of new and delete.

New and operator new

Many syntaxes in C ++ are hard to understand, such as: newOperator (operator, the same below)And operator new,

Specifically, it should be the difference between new and operator new.

The following code:

String * ps = new string ("memory management ");

The new operator is built in the C ++ language. Just like sizeof, it cannot change meaning and always does the same thing.

The action has two meanings:

First, it allocates enough memory to place certain types of objects. For the above example, it is allocated enough memory to place a string object.

Second, it calls a constructor to set the initial value for the object in the memory just allocated.

New operator always does these two things. In any case, you cannot change its behavior.

What can be changed is the allocation behavior of the memory used to hold the object. new operator calls a function to execute the necessary memory allocation action. You can rewrite or reload the function to change its behavior. The name of this function is operator new. Is it dizzy?

The operator new function is usually declared as follows:

Void * operator new (size_t size );

The return type void *. Returns a pointer pointing to an original memory with no initial value set.

The size_t parameter in the function indicates the amount of memory to be allocated. You can overload operator new with additional parameters, but the first parameter type must always be size_t.

Or you have never directly used operator new. But you can call it like any other function.

Void * rawMemory = operator new (sizeof (string ));

Operator new here will return a pointer, which refers to a few pieces of memory that can hold the string object.

Like malloc, the only task of operator new is to allocate memory. It does not know what constructor is. It is only responsible for allocating memory.

It is the responsibility of new operator to retrieve the memory returned by operator new and convert it into an object.

When the compiler sees this sentence:

String * ps = new string ("memory management ");

It must generate some code that will more or less reflect the following behavior:

Void * memory = operator new (sizeof (string); // gets the original memory, used to place a string object

Call string: string ("memory management") on * memory; // initializes an object in the memory.

String * ps = static_cast <string *> (memory); // point the ps to the newly completed object.

Note that step 2 calls a constructor. As a programmer, the new operator does not have the right to use constructor like this, but the compiler does.

This is why new operator must be used if you want to create a heap-based object.

That is to say, all new things are placed in heap, and you cannot directly call the constructor required for object initialization ".

 

Placement new

Sometimes you really want to directly call a constructor and call its constructor for an existing object. This is meaningless because the constructor is used for object initialization and the object can only be initialized once. However, you occasionally have some allocated original memory. You need to build an object on it. In a special case, operator new is called placement new, which allows you to do so.

For example:

Class Widget

{

Public:

Widget (int widgetSize );

......
};

Widget * constructWidgetInBuffer (void * buffer, int size)

{

Return new (buffer) Widget (size );
}

This function returns a pointer pointing to a Widget object, which is constructed in a memory cache zone passed to this function. When the program runs to the shared memory or memory I/O ing. Such functions may be useful because objects must be placed at specific addresses or in Memory allocated by special functions.

Function internal

Widget * constructWidgetInBuffer has only one expression new (buffer) Widget (size ),

It's a bit strange, but it's not surprising. It's one of the usage of new operator, where an additional independent variable (buffer) is specified as the new operator "implicitly Calling operator new. Therefore, the called operator new not only accepts "must have size_t independent variable", but also accepts a void * parameter, pointing to a piece of memory, ready to accept the constructed object. Operator new is the so-called placement new, which is similar:

Void * operator new (size_t size, void * location)

{

Return location;
}

Operator new aims to find a piece of memory for the object, and then returns a pointer pointing to it. In the case of placement new, the caller already knows the pointer pointing to the memory, because the caller knows where the object should be put. Therefore, the only thing placement new needs to do is to return the pointer it obtains.

As for the size_t parameter that is not used (but must have), the reason why the name is not given is to avoid the warning of "the compiler is not used.

Note: placement new is part of the C ++ standard library. To use placement new, use # include <new>. to use older compilers, use # include <new. h>.

Looking back at placement new, we can understand the relationship between new operator and operator new.

The two terms are confusing on the surface, but are actually easy to understand:

If you want to generate an object from heap, you get new operator, which not only allocates memory but calls a constructor for the object. ,

If you only want to allocate memory, use operator new so that no constructor is called.

If you plan to generate your own memory allocation method in the heap object, write your own operator new. And use new operator, which will automatically call the operator new you wrote.

If you plan to construct an object in the allocated memory (with pointers), use placement new.

 

 

Delete and memory release

To avoid resource leaks, each dynamic allocation action must match a corresponding release action.

The operator delete function has the same built-in delete operator (operator) as operator new and new operator.

String * ps;

...

Delete ps; // use delete operator.

The memory release action is executed by operator delete. The statement is as follows:

Void operator delete (void * memoryToBeDeallocated );

Therefore, delete ps;

The compiler code is as follows:

Ps-> ~ String (); // call the Analysis Function

Operator delete (ps); // release the memory occupied by the object

We are prompted that if we only want to process the original memory with no initial values, we should completely avoid new operator and delete operator.

Call operator new to obtain the memory and return it to the system with operator delete.

For example:

Void * buffer = operator new (50 * sizeof (char); // allocates memory and places 50 char records. No constructor is called.

...

Operator delete (buffer); // release the memory without directly calling the destructor.

This group of behaviors is similar to malloc and free.

 

If placement new is used to generate objects in a memory, you should avoid using delete in that memory.Operator).

Because deleteOperatorOperator delete is called to release the memory, but the objects contained in the memory are not originally allocated by operator new.

Placement new only returns the pointer it receives. Who knows where the pointer comes from?

To offset the influence of the constructor of the object, you should call the destructor of the object directly when using placement new.

See the example:

Void * mallocShared (size_t size); // apply for memory allocation

Void freeShared (void * momery); // release the memory.

Void * sharedMemory = mallocShared (sizeof (Widget ));

Widget * pw = constructWidgetBuffer (sharedMemory, 10); // use the placement new of the previous Widget class

...

Delete pw; // no definition, because sharedMemory comes from mallocShared, not from new

Pw-> ~ Widget (); // OK, The Destructor pw refers to the Widget object, but releases the memory occupied by the Widget.

FreeShared (pw); // OK, which releases the memory referred to by pw and does not call any destructor.

As shown in the preceding figure, if the raw memory assigned to placement new is dynamically allocated, the memory must be released to avoid the memory leak.

For more detailed analysis, see Counting Objects in C ++

 

Array (Arrays)

 

The previous steps are based on a single object. What if it is a group of objects?
String * ps = new string [10]; // allocate an array of Objects
1. The new here is similar to the previous new action, but slightly different. Here, operator new cannot be allocated memory, but operator new [] is responsible for allocation.
Like operator new, operator new [] can also be overloaded.
Note: operator new [] is a feature added to C ++ quite late, so your compiler may not support it. In this case, the global operator new will be used to allocate memory for each array (regardless of the type of objects in the array ). It is very difficult to customize the "Array Memory Allocation behavior" under such a compiler, because you have to rewrite the global operator new. By default, operator new in the global version is responsible for all the dynamic memory allocation in the program, so any change in its behavior may have a global impact.

In addition, operator new allows only one size_t parameter. So if you decide to declare your function as your own, your program will not be compatible with any library that has made the same decision.
If the compiler does not support operator new [], it is not a wise decision to customize the Array Memory Management Behavior.
2. Unlike the constructor called by the new object of an array, the new object of an array must call a constructor for each object in an array.
String * ps = new string [10]; // call operator new [] to allocate enough memory for 10 string objects, and then call the default constructor of string for each element.
Similarly, when delete is used, it

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.