[C/C ++] [classic discussion] whether memory leakage is caused by the release of the base class pointer delete in class inheritance

Source: Internet
Author: User

[Preface]
I haven't written C/C ++ technical posts for a long time, so I can use C ++ 7 ~ After eight years, although Delphi is widely used, I still have a passion for C ++. some time ago I saw a post on csdn, which made me feel very lost. Many people did not reference the authoritative document to discuss this issue. If there is no reference to the full-text document, the discussion will be a constant battle. to end this situation, the book shall prevail. If you all like to explore the technology, you can join my QQ: 643439947 to learn together.

[Suggestion]
C ++ is a very important and profound language. without 10 years of use and a large number of C ++ books to read, it is best not to easily explore some features of C ++, or it is really a stone to hit your own feet. for these reasons, I have rarely answered C ++ questions in csdn, because C ++ has too many details to pay attention to. The more I know, the more I feel that I am a C ++ cainiao. I am afraid that the answer is wrong.

[Thanks]
Zeng banxian, simple but not simple.

[Applicability]
This question involves too many knowledge points and a wide range of knowledge. I specifically classify it as a Windows desktop system. if someone suddenly involves embedded systems and embedded compilers, there will be no end to it. the following figure shows the ideas and scope provided by the document. We can imagine that there are too many unpredictable factors. "You may consider embedding the development environment. Although syntactically supported, the Library does not implement new and delete, which leads to uncertainties. In particular, programmers like templates and optimization, memory Pool usage"

[Principles]
I am a neutral person, not targeting anyone, but the problem. after analyzing this question, I have reviewed C ++. this issue involves five major issues of the new/delete function derived from the Destructor virtual function constructor. with a serious academic attitude, I read the following C ++ books:
1> C ++ primer plus
2> C ++ programming philosophy 2-book a new version
3> Objective C ++
4> imperfect C ++

[Csdn link that causes the problem]
Http://topic.csdn.net/u/20110715/15/7ca1e66b-8a04-4c90-80f0-6265ff0269af.html? 91968

[Restoration problem]
Class
{
Public:
A (){};
~ A () {}; // Ooops must use virtual ~ A ()
};

Class B: public
{
Public:
B (){};
~ B (){};
};

Int main ()
{
A * pclass_a = new B; // create a B object pointer and implicitly convert it to *

// Here we need to note that this conversion involves a concept called upcast.
Delete pclass_a;
Pclass_a = NULL;
Return 0;
}

[Analysis conclusion]
As far as this code is concerned, I have read four books and have not clearly stated that such a writing method may leak. however, it can be determined that such writing is a implicit error, which violates the C ++ inheritance rules and the implementation principle and mechanism that violates inheritance.
See http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.7 for details

"... It is a implicit error to not set the Destructor as a virtual function, because it often does not directly affect the program. But be aware that it does not feel the introduction of Memory leakage (Closing the program is to release the memory ). Similarly, such an destructor may also mask the problem... "(from the C ++ programming idea 2 book, page 1 ). Although this sentence is short, it answers many of our questions.

1> "if you do not use a virtual destructor, it will not directly affect the program ". here, "there is no direct impact on the program", we can consider that delete a base class pointer (the base class has no destructor ), does not leak memory (for the above Code only, if there is a heap allocated in the derived class, there will certainly be a memory leak ).
Here, why do we think that deleting a base class pointer (the base class has no destructor) will not result in memory leakage? This is the special mechanism and responsibility of C ++'s new and delete. Let's take a look at this sentence:
".... When an object is actively created in the stack, the object size and their declaration cycle are accurately embedded in the generated code, because the compiler knows the exact type, quantity and range ..... "(from the 318th page of C ++ programming ideology 2) clearly tells us that we will know the exact" type, quantity, and range ", note that there is a "range" here, so we can infer that using the base class pointer to delete will not directly affect the program. (Note: Please understand, I did not dare to say that there would be no memory leakage, because I could not verify with the compiler vendor, But I think "should" not cause memory leakage ).


2> "but note that it may introduce Memory leakage without knowing it" added to the previous sentence, special emphasis is placed on "imperceptible" + "Introduction" + "Memory leakage ". obviously, if a leak occurs, it is caused by external personnel. For example, the new operation is used in Class B, for example, applying for a 10-byte char
* Char_a = new char [10], if you do not declare the destructor of the base class and define it as virtual, when class B is released, it is impossible to clean up the final field. for example, the new char [10] cannot be released.

In addition: In the class inheritance mechanism, constructor and destructor have a special mechanism called
"Layer-chain call notification", which is based on "vpointer" "vptr" and "vtable" (from: C ++ programming idea 2-volume subscription 369th page) (Note: layer-chain call notification is a word I personally understand and summarize. you can read the C ++ programming idea 2 book, 385th page ).
The process is as follows: when constructing a class with a class inheritance mechanism, for example, Class B above, the Class A structure will be called first, after a's construction is complete, Class B's constructor is called to achieve the effect of "from inside to outside" notification calls. if a class with a class inheritance mechanism is released, Class B's destructor will be called, and Class A's destructor will be called to achieve the effect of "from outgoing to outgoing" Notification notifications, in order to achieve this "layer-chain call notification" effect, the C ++ standard stipulates that the destructor of the base class must be declared as virtual,
If you do not declare it, the "layer-chain call notification" mechanism cannot be constructed. as a result, the destructor of the base class is called, but the destructor of the derived class is not called. however, pay special attention to the following: in this special case, the destructor of the derived class is not called, and in 2, the problem occurs:
1> if your derived class does not allocate any heap, but only a single local variable, they will be released according to the life cycle theory of local variables and classes, "It will not have a direct impact on the program" (Note: Please forgive me. I did not dare to say that there will be no memory leakage, because I have not been able to verify with the compiler vendor, but I am "should" not cause memory leakage), such as the code snippets listed at the top of this article.
2> if your derived class has a heap allocated internally, the derived class cannot clear the final field through its own destructor, such as Delete [];

[Csdn user pengzhixi provides the delete standard description]
Delete-expression:
: OPT Delete Cast-expression
: OPT Delete [] Cast-expression

In the first alternative (delete object), if the static type of the operand is different from its dynamic type, the static type shall be a base class of the operand's dynamic type and the static type shall have a virtual destructor or the behavior is undefined.
In the second alternative (delete array) if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined.
Translation:
For Delete object, if the static type of the delete object is different from that of the dynamic type, the static type must be a base class of the dynamic type, the static type must have a virtual destructor; otherwise, the behavior is not defined. In the form of Delete [], if the static and dynamic types are inconsistent, the behavior is undefined (even if your static type contains a virtual destructor, it is an error to use polymorphism for arrays)

[Problem Summary]
If you specifically Delete the object and the behavior is undefined, you still have to follow the developer's ass if there is any memory leakage. They say that there is, and they say that there is no, there is no. but there is one thing we must do: When writing C ++ code, do not do anything that does not conform to the standard. let the compiler developers solve or worry about undefined behaviors.

[End]
It took me one hour to write this article, but it took me two hours to read 4 C ++ books and try again to digest this classic problem.

[Query materials]
1> class inheritance in chapter 1 of C ++ primer plus
2> C ++ programming philosophy 2. Book chapter 1 Dynamic Object creation in the new version Chapter 2 Inheritance and combination Chapter 2 polymorphism and virtual functions

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.