Smart pointer Application Analysis of VC and C ++

Source: Internet
Author: User

Original article address:

Http://blog.csdn.net/tiger119/archive/2005/12/07/546303.aspx

Reposted from the blog space "Stone note"

 

 

 

Some time ago, when I checked for Control Memory leakage, I finally found an error: When I used xmldom (COM), the dispatch pointer (release) was not released because I used an interface pointer repeatedly ), as a result, memory leakage occurs, and such errors (such as BSTR type leaks), the VC debugger and bondcheck are powerless. The solution seems to be only careful.
However, if you take a closer look, you can find that using the smart pointer provided by VC can avoid this problem.
In addition, Java programmers have been talking about the advantage of memory usage without management, and they always know that C ++ smart pointers can be used for simulation. However, I have never actually started the analysis. I simply wrapped it in C ++. In a rough view, it can achieve the same effect as Java. Of course, the C ++ object is more efficient and saves memory.
As mentioned above, I can only list the time relationships. The Code should be correct (but not checked ). There is no logical relationship between the beginning and end, but if we want to further apply the smart pointer of C ++, we believe it will serve as an example.

I. Application of smart pointers in MFC and ATL for Error Correction
1: How to conveniently view the memory used by the current process in windows.
Although the code is simple, there is a lot of use for Error Correction. You don't have to switch the task manager to view the memory usage. The Code is as follows:
Uint c_baseutil: getprocessmemoryused ()
{
Uint uitotal = 0l;
HANDLE hProcess =: GetCurrentProcess ();
PROCESS_MEMORY_COUNTERS pmc;
If (: GetProcessMemoryInfo (hProcess, & pmc, sizeof (pmc )))
UiTotal = pmc. WorkingSetSize;
Return uiTotal;
}
Note: memory usage is an unstable process. Therefore, you need to call it when the program is stable to ensure accuracy.

2: if you do not use the Com smart pointer when using the Dispatch pointer of COM, it is prone to errors.
2.1: forget to release the pointer at all exits.
For example:
IXMLDOMDocument * pDoc = NULL;
CoCreateInstance (...)
......
PDoc-> Release ();
Error: if an exception occurs in the intermediate code, pDoc cannot be properly released, resulting in Memory leakage.

2.2: The same pointer variable is used repeatedly, causing the Dispatch pointer generated in the middle to fail to be released.
IXMLDOMNode * pNode = NULL;
If (FAILED (pDoc-> selectSingleNode (_ bstr_t ("Workbook"), & pNode) | pNode = NULL)
Throw (_ T ("selectSingleNode failed! "));
If (FAILED (pDoc-> selectSingleNode (_ bstr_t ("Workbook"), & pNode) | pNode = NULL)
Throw (_ T ("selectSingleNode failed! "));
Error: the second call is started when pNode is not released, resulting in Memory leakage. Or something similar to pNode = pNode2 is also a problem. You must call if (pNode) {pNode-> Release (); pNode = NULL ;}
 
3: Use the Com smart pointer provided by MFC to solve the above problem.
Note: You can view the source code and see that the prototype of the smart pointer generated by # import is _ com_ptr_t.
3.1:
IXMLDOMDocumentPtr docPtr = NULL;
DocPtr. CreateInstance (...)
......
OK. This will not cause any problems, because docPtr will correctly release the structure.

3.2:
IXMLDOMNodePtr nodePtr = NULL;
If (FAILED (pDoc-> selectSingleNode (_ bstr_t ("Workbook"), & nodePtr) | nodePtr = NULL)
Throw (_ T ("selectSingleNode failed! "));
If (FAILED (pDoc-> selectSingleNode (_ bstr_t ("Workbook"), & nodePtr) | nodePtr = NULL)
Throw (_ T ("selectSingleNode failed! "));
OK, no error will occur, because _ com_ptr_t reloads the & operator. The following operations are available when getting the pointer: Hey.
Interface ** operator & () throw ()
{
_ Release ();
M_pInterface = NULL;
Return & m_pInterface;
}

3.3: nodePtr = nodePrt2, and no problem occurs:
Check the source code carefully and call Attach in the = Operator. Attach calls _ Release () first ();

3.4: Let's look at the value transfer: the copy constructor is as follows:
Template <> _ com_ptr_t (const _ com_ptr_t & cp) throw ()
: M_pInterface (cp. m_pInterface)
{
_ AddRef ();
}
Well, there will be no problem.

3.5: Finally, We will summarize the considerations when using the COM smart pointer:
3.5.1: do not enable the life cycle of the Com smart pointer. If it is after: CoUninitailize, forcibly call MyComPtr = NULL before: CoUninitailize. Otherwise, an error occurs.

3.5.2: Do not mix smart pointers and general Dispatch pointers. Do not call MyComPtr-> Release (). This violates the smart pointer's original intention and will report an error in the analysis structure.

4: Use ATL to provide smart pointers: CComPtr or CComQIPtr.
If you do not use the MFC framework, you must package IDispatch to generate a smart pointer. You can also use the smart pointer provided by ATL.
View the source code, and refer to the in-depth analysis of ATL book, found that the implementation is similar to _ com_ptr_t, the effect is consistent.

Ii. Let's look at the smart pointer of C ++.

1: When it comes to smart pointers, we must look at the auto_ptr provided by the Standard C ++.
There are many restrictions on the use of auto_ptr. We will calculate the number one by one:
1.1: auto_ptr requires that an object only has one owner.
For example, the following is incorrect.
ClassA * pA = new classA;
Auto_ptr <classA> ptr1 (pA );
Auto_ptr <classA> ptr2 (pA );

1.2: auto_ptr cannot be passed by passing values.
The transfer of ownership will cause the passed smart pointer to lose its ownership of the pointer. If you want to transfer, you can use the reference method. Using the const reference method can also avoid the transfer of ownership in other methods in the program. In terms of ownership transfer: You can view the copy structure of auto_ptr and the source code of the = Operator, Which is omitted here.

1.3: Other considerations:
1.3.1: arrays are not supported.
1.3.2: note the meaning of its Release. It does not reference the count. It is different from the smart pointer provided by com. Release refers to releasing the pointer, that is, handing over the ownership of the pointer.
1.3.3: the unique Pearl meaning of auto_ptr in copying constructor and = operator determines that it cannot be a member of STL standard containers,

Well, after reading the above precautions, especially 1.3.3, we can basically draw a conclusion that auto_ptr has little application value in actual application scenarios.

2: How to Get Smart pointers that support containers.
We use the auto_ptr prototype to create a smart pointer for reference counting, so that it supports the STL container standards.
The implementation code is very simple. Refer to the Code in C ++ standard library. The key code is as follows:
Template <class T>
Class CountedPtr {
T * ptr;
Long * counter;
Public:
// Construct
Explicit CountedPtr (T * p = NULL)
: Ptr (p), count (new long (1 ){}
// Structure
~ CountedPtr () {Release ();}
// Copy Structure
CountedPtr (cont CountedPtr <T> & p)
: Ptr (p. ptr), count (p. count) {++ * counter ;}
// = Operator
CountedPtr <T> & operator = (const CountedPtr <T> & p ){
If (this! = & P ){
Release (); ptr = p. ptr; counter = p. counter; ++ * counter;
}
Return * this;
}
// Others
....
PRIVATE:
Void release (){
If (-- * counter = 0 ){
Delete counter;
Delete PTR;
}
}
}

Okay. In this way, when the smart pointer is copied, the original pointer and the new pointer copy are both valid and can be applied to containers.
Now, is the c ++ object packaged through countedptr similar to the Java object.
As long as some necessary operators are added, they can be used as shared resources in the container.

Stone

 

This article from the csdn blog, reproduced please indicate the source: http://blog.csdn.net/tiger119/archive/2005/12/07/546303.aspx

 

 

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.