Search code examples
.netvisual-c++memory-managementcomheap-corruption

C++ delete statement throws Heap corrupted exception in .net 4.5 process


Earlier i had a .net client application (console application) whose target framework is set as 4.0. The client code looks like ,

    COMProxyCustomClass proxy = new COMProxyCustomClass();
    proxy.LoadFieldServiceComponent("abc", 3); 

where the .net client make use of C++ COM type COMProxyCustom via reference to a RCW interop dll generated by importing TLB of the C++ com project. The implementation of LoadFieldServiceComponent method looks like ,

    STDMETHODIMP CCOMProxyCustom::LoadFieldServiceComponent(BSTR fscName, int version)
    {
   HRESULT hr = S_OK;   
   ILocaleManager *localeManager = NULL;
   hr = CoCreateInstance(CLSID_LocaleManager, NULL , CLSCTX_ALL , IID_ILocaleManager,      (void**)&localeManager);
   delete(localeManager);
   localeManager = NULL;
   return hr;
    }

Again here ILocaleManager is a .net type which gets used in the C++ project by exporting a TLB from the .net project and including/importing it here in the C++ com project.

    #import "SomeInterop.tlb" no_namespace named_guids

Till here everything is alright.

Here comes the problem , to make use of the features provided by .net 4.5 (System.IO.Compression) i moved the C# client project now to target .net 4.5 version(earlier it was .net 4.0). After doing this migration , i started getting a heap corrupted error at the statement delete(localeManager).

Error message from VS debugger

Now why do we get this error when this particular statement (delete) gets executed in a .net process which targets 4.5 and why not in 4.0 , is there any change in how the memory should be freed in C++ code if the .net application which loads this C++ code targets 4.5 framework version ? and how to clear the memory of localeManager now if delete cant be used ?


Solution

  • You're using COM, you should call Release() on localeManager instead of deleting it.

     if (localeManager)
         localeManager->Release();
    

    COM use reference count to manage object life cycle.

    As C++ delete key word, it has to know the type of the pointer, it relies on C++ RTTI to works; as to COM, it has different RTTI implementation. COM object has different layout structure than C++ object.

    As you said, delete works earlier, it really doesn't. Deleting that a COM pointer will corruptthe heap, however, it won't crash at the line of delete statement; the behavior is: your program sometime crashes, sometime not.