C++;delete语句在.net 4.5进程中引发堆损坏的异常

C++;delete语句在.net 4.5进程中引发堆损坏的异常,.net,visual-c++,memory-management,com,heap-corruption,.net,Visual C++,Memory Management,Com,Heap Corruption,之前我有一个.net客户端应用程序(控制台应用程序),其目标框架设置为4.0。 客户端代码看起来像 COMProxyCustomClass proxy = new COMProxyCustomClass(); proxy.LoadFieldServiceComponent("abc", 3); STDMETHODIMP CCOMProxyCustom::LoadFieldServiceComponent(BSTR fscName, int version) {

之前我有一个.net客户端应用程序(控制台应用程序),其目标框架设置为4.0。 客户端代码看起来像

    COMProxyCustomClass proxy = new COMProxyCustomClass();
    proxy.LoadFieldServiceComponent("abc", 3); 
    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;
    }

其中.NET客户端通过引用C++ COM项目导入TLB生成的RCW互操作DLL,使用C++ COM类型COMPRYXORIVE。 LoadFieldServiceComponent方法的实现如下所示:

    COMProxyCustomClass proxy = new COMProxyCustomClass();
    proxy.LoadFieldServiceComponent("abc", 3); 
    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;
    }

再次,ILocaleManager是.NET类型,它通过从.NET项目导出TLB并在C/C++ COM项目中包含/导入TB来使用C++项目。

    #import "SomeInterop.tlb" no_namespace named_guids
直到这里一切都很好

问题来了,为了利用.NET4.5(System.IO.Compression)提供的功能,我现在将C#客户端项目移动到了目标.NET4.5版本(早期是.NET4.0)。完成此迁移后,我开始在语句delete(localemager)中发现堆损坏错误


现在,当这个特定语句(删除)在目标为4.5的.NET进程中执行,为什么在4中执行时,我们会得到这个错误,如果加载这个C++代码的.NET应用程序针对4.5框架版本,内存应该如何释放,在C++代码中有什么变化吗?如果无法使用delete,现在如何清除localeManager的内存?

如果您使用的是COM,您应该调用localeManager上的Release(),而不是删除它

 if (localeManager)
     localeManager->Release();
COM使用引用计数来管理对象生命周期

作为C++删除关键字,它必须知道指针的类型,它依赖C++来工作;对于COM,它有不同的RTTI实现。COM对象的布局结构与C++对象不同。


正如你所说的,删除在更早的时候起作用,但实际上并不起作用。删除COM指针将损坏堆,但是,它不会在delete语句行崩溃;其行为是:您的程序有时崩溃,有时不崩溃

是的,我明白。但是你知道为什么delete语句在更早的时候起作用而不是现在吗?我想了解更多关于删除部分的信息。@srsyogesh修改了我的回答Thank@Matt,虽然我知道我们需要使用release方法释放COM对象,但到目前为止,我没有意识到delete语句用于释放应用程序中的内存。但有趣的是,我更关注于它为什么能更早工作,为什么不能现在工作。我在想,可能是新的.net framework 4.5引入了这种行为,如果是这样的话,那是什么呢?正是这种兴奋让我发布了这个问题。无论如何,再次感谢您的解释。@srsyogesh one不是,这不是由.NET介绍的。COM比.NET“旧”