In C + +, you may often use new and delete to dynamically request and free memory, but have you ever thought about the following issues?
- are new and delete functions?
- What are new [] and delete []? When do you use them?
- Do you know operator new and operator delete?
- Why is the array of new [] can sometimes be released with delete and sometimes not?
- ...
If you have any questions about these questions, you might want to check out this article.
What exactly is new and delete?
If the students looking for a job look at some of the interview books, I believe they will encounter such a problem: sizeof is not a function, and then cite a bunch of reasons to prove that sizeof is not a function. Here, like sizeof, new and delete are not functions, they are all keywords that are defined by C + +, and can be made into expressions through specific syntax. Unlike sizeof, sizeof can determine its return value at compile time, and the mechanism behind new and delete is more complex.
Before you go down, think about what you think new should do? Perhaps your first reaction is that new is not just like the malloc function in C, it is used to dynamically apply for space. You're half right, look at the following statement:
*string("Hello World");
You can see that the new and malloc are a little different, and malloc does not make the necessary initialization of memory after the application is completed, and new can. So the thing behind new expression is not as simple as you think. Before I use an example to explain the mechanics behind new, you need to operator new
know operator delete
what it is.
operator new AND operator delete
These two are actually library functions of the C + + language standard library, the prototypes are as follows:
void *operator new (size_t//allocate an objectvoid *operator delete (void *//free an objectvoid *operator New[] (size_t//allocate an arrayvoid *operator delete[] (void *//free an array
The next two you can not see first, the following introduction. The first two are all C + + standard library functions, you might think this is a function? Please do not doubt, this is the function! C + + Primer that this is not overloaded with new and delete expressions (such as operator=
overloading = operators), because new and delete are not allowed to be overloaded. But I haven't figured out why it's operator new and operator delete to name it. As long as we know what they mean, these two functions are a bit like the malloc and free functions in C, they are used to request and release memory, and operator new requests memory without initializing the memory, directly returning a pointer to the request memory.
We can use these functions directly in our program.
The mechanism behind new and delete
Knowing the above two functions, we use an example to explain the mechanism behind the new and delete:
We do not use simple C + + built-in types for example, using a more complex class type, defining a Class A:
ClassA{PublicA (int v) : var< Span class= "P" > (v) {fopen_s ( Span class= "o" >&file "test" "R" ); } ~a () {fclose< Span class= "P" > (file}private: int varfile *file;};
Quite simply, there are two private members in Class A, a constructor and a destructor, a constructor that initializes the private variable var and opens a file, and the destructor closes the open file.
We use
*A(ten);
To create an object of a class that returns its pointer to PA. As shown in the work done behind the new:
Briefly summarize:
- First you need to call the operator new standard library function mentioned above, the passed parameter is the size of class A, here is 8 bytes, as for why 8 bytes, you can look at the "in-depth C + + object Model" a book, here do not long explanation. This function returns the starting address of the allocated memory, which is assumed to be 0x007da290.
- The memory allocated above is uninitialized and untyped, the second step is to initialize the class object on this piece of raw memory, call the corresponding constructor, here is call
A:A(10);
This function, also can see the memory of this application is initialized var=10, file 指向打开的文件
.
- The final step is to return a pointer to the newly allocated and constructed object, where PA points to the 0x007da290 memory, and the PA type is a pointer to the class A object.
All three steps, you can find the corresponding assembly code through disassembly, here I will not list.
Okay, so what did the delete do? Or the above example, what if you want to release the object of the application class? Of course we can use the following statement to complete:
PA;
The delete Does the same thing as the following:
Delete has done two things:
- Call the PA to point to the object's destructor and close the open file.
- Using the standard library function mentioned above operator delete to free the memory of the object, the parameter passed into the function is the value of PA, that is, 0x007d290.
Well, is it easy to explain what happened behind new and delete? No more than a call to a constructor and destructor.
How do I request and release an array?
We often use the dynamic allocation of an array, perhaps this:
*string[//array of ten Empty strings*int[//array of10 Uninitialized ints
This expression is used to complete the application of an array, as new []
we mentioned above for the new and delete knowledge, the first array is a string type, after allocating the memory space to save the object, the string will be called The default constructor for a type initializes each element of the array in sequence, and the second is to request an array with a built-in type, allocating memory space for storing 10 int objects, but not initialized.
If we want to free up space, we can use the following two statements:
PSA; Pia;
All use delete []
expressions, note that this place [] can not be missed in general! We can also imagine what these two statements did: the first one called a destructor on 10 string objects, and then freed up all the memory space allocated for the object, and the second one, because the built-in type does not have a destructor, directly frees all memory space allocated for the 10 int type.
Here's a question for the first case: How do we know the size of the array that the PSA points to the object? How do I know how many destructors to call?
This problem directly leads us to need to save the dimension of the array when new [] An array of objects, C + + is the practice of allocating array space when the allocation of more than 4 bytes of size, specifically to save the size of the array, the delete [] can be taken out of the saved number, You'll know how many times you need to call the destructor.
Or the diagram to illustrate the more clear, we define a Class A, but do not specifically describe the contents of the class, the class has a display of constructors, destructors, and so on. So when we call
*A[3];
The things you need to do are as follows:
From this figure we can see that at the time of the application, there are more than 4 bytes allocated on top of the array object to hold the size of the array, but the end result is a pointer to an array of objects, not the starting address of all allocated space.
In this case, the release is simple:
Delete []pAa;
The two points to note here are:
- The number of times the destructor is called is taken from the 4 bytes in front of the array object pointer;
operator delete[]
the parameter passed into the function is not a pointer to the array object PAA, but the value of PAA minus 4.
Why are New/delete, new []/delete[] paired?
Actually said so much, not yet to write this article the most original intention. As explained above, you should understand how new/delete and new[]/delete[] work, because there are differences between them, so they need to be paired with each other. But the problem is not so simple, this is the problem I encountered, the following code:
*int[ten]; []pia;
This is sure to be fine, but what if you delete []pia;
change it delete pia;
?
This involves a question that is not mentioned in the previous section. I mentioned the reason for new []
allocating more than 4 bytes at the time, because the size of the array needs to be known, but what if the destructor is not called (such as the built-in type, the int array here)? There new []
is no need to allocate the 4 bytes more When we are there, and delete [] releases the space allocated for the int array directly to the second step. If this is used delete pia;
then the function will be called operator delete
, and the passed argument is the starting address assigned to the array, and the thing to do is to release the memory space. There's no problem.
It says here that using new []
Delete to release an object is in advance: the type of the object is a built-in type or a class type that has no custom destructor!
Let's see if it's a class type with a custom destructor, new []
create an array of class objects, and use Delete to release what happens? Use the example above to illustrate:
*A[3]; PAa;
Then delete pAa;
two things are done:
- Call the destructor of the object that the pAa points to;
- Call
operator delete(pAa);
to free memory.
Obviously, only the first class object of the array is called the destructor, the following two objects do not call the destructor, if the class object request a lot of memory needs to be released in the destructor, and you are destroying the array object when the destructor is less called, which will cause a memory leak.
If you say nothing about the above question, then the 2nd is deadly! The direct release of the PAa point to the memory space, this will always cause a serious segment error, the program will inevitably crash! Because the starting address of the allocated space is where the pAa points minus 4 bytes. You should pass in the parameter set to that address!
Similarly, you can analyze what will happen if you use new to allocate and delete []
release? Does it always cause program errors?
In general, remember a little:New/delete, new[]/delete[] to use the same is always true!
Resources:
C + + Primer fourth Edition
"Turn" on New/delete and new[]/delete[in C + +]