More efficient C ++: understanding new and delete

Source: Internet
Author: User
Reprinted from:
Http://dev.yesky.com/242/2585242.shtml

Sometimes people seem to like to deliberately make the terms in the C ++ language hard to understand. For example, the difference between the new operator and operator new.

When you write this Code:

String * PS = new string ("Memory Management ");

You use the new operator. This operator is just like sizeof which is built in a language. You cannot change its meaning and its functions are always the same. The functions to be completed are divided into two parts. The first part is to allocate enough memory to accommodate the required types of objects. The second part is that it calls the constructor to initialize objects in the memory. The new operator always does these two things, and you cannot change its behavior in any way.

What you can change is how to allocate memory to objects. The new operator calls a function to complete the necessary memory allocation. You can rewrite or reload the function to change its behavior. The new operator indicates that the name of the function called for memory allocation is Operator new.

The operator new function is usually declared as follows:

Void * operator new (size_t size );

The return value type is void *, because this function returns an unprocessed (raw) pointer with uninitialized memory. (If you like it, you can write an operator new function. Before returning a pointer, You can initialize the memory to store some values, but this is generally not the case .) The size_t parameter determines how much memory is allocated. You can add an extra parameter to overload the function operator new, but the first parameter type must be size_t. (For more information about operator new, see invalid tive C ++ clauses 8 to 10 .)

You generally do not directly call operator new, but once you do so, you can call it like calling other functions:

Void * rawmemory = Operator new (sizeof (string ));

The operator new returns a pointer pointing to a memory sufficient to accommodate a string type object.

Like malloc, operator new only allocates memory. It knows nothing about constructors. Operator new understands memory allocation. It is the work of the new operator to pass the unprocessed pointer returned by operator new to an object. When your compiler encounters such a statement:

String * PS = new string ("Memory Management ");

The code generated by it is more or less similar to the following code (for more details, see article 8 and article 10 of Objective C ++, as well as comments in my article counting object .) :

Void * Memory = // get unprocessed memory
Operator new (sizeof (string); // String object
Call string: string ("Memory Management") // Initialization
On * memory; // memory in progress

// Object

String * PS = // PS pointer
Static_cast <string *> (memory); // new object

Note that the second step contains the call of the constructor. You are not allowed to do this as a programmer. Your compiler does not have this constraint. It can do everything it wants. Therefore, if you want to create a heap object, you must use the new operator. You cannot directly call the constructor to initialize the object.

Placement new

Sometimes you really want to call the constructor directly. Calling a constructor on an existing object is meaningless, because the constructor is used to initialize the object, and an object can only be initialized once when it is given an initial value. But sometimes you have some (raw) memory that has been allocated but not yet processed, You need to construct an object in the memory. You can use a special operator new called Placement new.

The following example shows how to use placement new. Consider the following:

Class widget {
Public:
Widget (INT widgetsize );
...
};

Widget * constructwidgetinbuffer (void * buffer, int widgetsize)
{
Return new (buffer) widget (widgetsize );
}

This function returns a pointer pointing to a widget object, which is allocated in the buffer transferred to the function. This function may be useful when the program uses shared memory or memory-mapped I/O, in such a program, objects must be placed in a fixed address or a memory allocated by the routine. (See Clause 4. A different example of how to use placement new .)

In constructwidgetinbuffer, the returned expression is:

New (buffer) widget (widgetsize)

This seems a little unfamiliar at first, but it is a usage of the new operator and requires an additional variable (buffer). When the new operator implicitly calls the operator new function, pass this variable to it. In addition to the mandatory size_t parameter, the called operator new function must also accept the void * pointer parameter, pointing to the memory space occupied by the constructor. This operator new is placement new, which looks like this:

Void * operator new (size_t, void * location)
{
Return location;
}

This may be simpler than you expected, but this is what placement new needs to do. After all, operator new aims to allocate memory for the object and then return a pointer to the memory. When placement new is used, the caller has obtained a pointer to the memory, because the caller knows where the object should be placed. What placement new must do is return the pointer to it. The size_t parameter (useless (but mandatory) has no name to prevent the compiler from issuing a warning that it is not in use. See Clause 6 .) Placement new is part of the standard C ++ Library (see article 49 ). To use placement
New, you must use the statement # include <New> (or if your compiler does not support this new style of header file name (see article 49 of Objective C ++), <New. h> ).

Let's take a moment back from placement new to see the relationship between the new operator and operator new. To create an object on the stack, you should use the new operator. It allocates both memory and calls constructors for objects. If you only want to allocate memory, you should call the operator new function; it will not call the constructor. If you want to customize your memory allocation process when the heap object is created, you should write your own operator new function and then use the new operator, the new operator calls your customized operator new. If you want to create an object in a memory with obtained pointers, you should use placement
New.

(For more ideas about new and delete, see article 7 of Objective C ++ and my article counting objects .)

Deletion and memory deallocation

To avoid Memory leakage, each dynamic memory allocation must correspond to an equivalent deallocation. The relationship between the operator Delete and delete operators is the same as that between operator new and new operators. When you see the code:

String * pS;
...
Delete pS; // use the delete Operator

Your compiler will generate code to analyze the object and release the memory occupied by the object.

Operator Delete is used to release memory. It is declared as follows:

Void operator Delete (void * memorytobedeallocated );

Therefore, delete pS;

The compiler generates code similar to this:

PS-> ~ String (); // call the object's dtor
Operator Delete (PS); // deallocate the memory
// The object occupied

This implies that if you only want to process uninitialized memory, you should bypass the new and delete operators and call operator new to obtain the memory and operator Delete to release the memory to the system:

Void * buffer = // allocate enough
Operator new (50 * sizeof (char); // memory to accommodate 50 char

// No constructor is called
...
Operator Delete (buffer); // releases memory
// The Destructor is not called.

This is equivalent to calling malloc and free in C.

If you use placement new to create objects in the memory, you should avoid using the delete operator in the memory. Because the delete operator calls operator Delete to release memory, but the memory containing objects is not initially allocated by operator new, placement new is just a pointer to it. Who knows where the pointer comes from? Instead, you should explicitly call the object's destructor to relieve the constructor's impact:

// Function void * mallocshared (size_t size) for allocating and releasing memory in the shared memory );

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 unknown! Shared memory comes from

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.