Effective use and design of COM smart Pointers-cla13: You must release COM components in advance.

Source: Internet
Author: User
Article 13: must release COM components in advance, do not think smart pointer to help you complete more terms please go to the original article: http://blog.csdn.net/liuchang5

With smart pointers, you may not want to manually release or increase the reference count. In this case, please refer to the following functions:

Void insomewhere (ihello * phello) {ccomptr <ihello> sphello = phello; sphello-> dosomething (); hresult hR = cocreateinstance (clsid_hello null, empty, iid_ihello, (void **) & sphello // resource leakage may occur here); Assert (succeed (HR); sphello-> dootherthing ();}

You carefully checked the IID and pointer types and found no problem. In addition, the assert behind the cocreateinstance gives you full confidence in his behavior.

But the problem is that sphello originally meant something. Will it release the reference count of the corresponding interface? The answer is undefined.

IP address fetch operations for sphello in non-null conditions are defined differently in different smart pointers. For ccomptr, he will initiate an assertion during debugging, And the release version will quietly let the resource leak. For _ com_ptr_t, whether in relase or debug, it secretly releases crude oil resources without prompting the outside world about such dangerous operations.

Knowing the cause may be that you don't expect this dangerous operation to take the address character too much. You may have thought of the content described in "clause 11: creating resource sources and querying interfaces in a type-safe manner. Check whether there is a problem with the modified version below.

Void insomewhere (ihello * phello) {ccomptr <ihello> sphello = phello; sphello-> dosomething (); sphello. cocreateinstance (clsid_hello); // resource leakage assert (sphello); sphello-> dootherthing ();}

The problem still occurs, because cocreateinstance still makes an asserted when sphello is not empty in the debug version. Resources in release are leaked. For _ com_ptr_t, it is still quietly helping you release the resources first.

Therefore, the most secure response policy is: "You must release the COM component in advance, so don't think That smart pointers will help you complete it ".

Void insomewhere (ihello * phello) {ccomptr <ihello> sphello = phello; sphello-> dosomething (); sphello = NULL; // or sphello. release (); release the resource sphello in advance. cocreateinstance (clsid_hello); Assert (sphello); sphello-> dootherthing ();}

OK. The problem is resolved.

In some cases, memory leakage occurs because you have not manually released the COM component. Suppose we have designed such a container to store smart pointers as follows:

template<typename T>class MyStack{public:    MyStack(int nCapacity){        m_pArray = new T[nCapacity]();        m_nCapacity = nCapacity;        m_nTop= 0;    };    ~MyStack(){        delete[] m_pArray;    };    void push(T Item){        assert(m_nTop < m_nCapacity);        m_pArray[m_nTop++] = Item;    }    T pop(){        assert(m_nTop > 0);        return m_pArray[--m_nTop];    }    MyStack(const MyStack<T>& otherArray)    {        //deep copy it     };private:    T *m_pArray;    int m_nTop;    int m_nCapacity;};

The mystack process is as follows:

MyStack<CComPtr<ICalculator>> g_myStack(1000);void func(){    for (int i=0; i<500; i++)    {        CComPtr<ICalculator> spCalculator = NULL;        spCalculator.CoCreateInstance(CLSID_CALCULATOR);         g_myStack.push(spCalculator);    }           ...        for (int i=0; i<500; i++)    {        CComPtr<ICalculator> spCalculator = g_myStack.pop();        spCalculator->DoSomething();    }}

The 500 cocreateinstance () operation may make you feel crazy. But I just want to let you know how memory leakage happens.

Why? In this case, smart pointers cannot automatically release the corresponding resources. First, they are in the global space. If you want to wait ~ The Destructor mystack () may need to wait until the program ends. However, after pop, we should not store the smart pointer reference to the interface in mystack. Imagine that there would never be more than 500 elements in this mystack. Then, the resources in the second half of mystack will never be released.

Therefore, when you must manually release the COM component, do not think that the smart pointer will help you complete it. Just rewrite the POP () function and solve the resource leakage problem.

Template <typename T> class mystack {public :.... t POP () {assert (m_ntop> 0); t temparray = m_parray [-- m_ntop]; m_parray = NULL; // or m_parray.release (); Return temparray ;} PRIVATE :....};

Keep in mind that smart pointers only help us manage memory. You must release com resources in advance. This section can end.

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.