为什么一个标量删除析构函数作为向量删除在Windows上的结果被调用? [英] why is a scalar deleting destructor being called as a result of vector delete on Windows?

查看:181
本文介绍了为什么一个标量删除析构函数作为向量删除在Windows上的结果被调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个在Windows上泄漏的代码。它在许多unix平台上运行良好,泄漏只发生在Windows上。
二进制包括exe,1 dll和2个静态库。 exe链接到dll和静态库,而静态库也与dll链接。泄漏发生在exe代码中,而不是调用向量删除析构函数,由于某种原因标量删除析构函数被调用。这导致只有数组中的第一个对象被删除,而数组的其余部分保留在内存中。



泄漏的伪代码如下所示:

  class MyClassFromExe:public MyBaseClassFromDll {
public:
ClassFromDll * m_arr;

MyClassFromExe(unsigned int size)
{
m_arr = new ClassFromDll [size];
}

〜MyClassFromExe()
{
delete [] m_arr;
}
};

void func()
{
MyClassFromExe obj(3);
}

当func()完成并且析构函数被调用时,我看到只有析构函数的m_arr中的第一个对象被调用。从调试器,我看到这是从标量删除析构函数,而不是从矢量删除析构函数。这解释了为什么只有第一个对象被销毁。
我需要理解的是为什么使用delete []时调用标量删除析构函数



我发现这个线程 - 为什么矢量删除析构函数被称为标量删除的结果?。我遵循那里的建议,并确保所有的模块都编译/ MD。



重要的是要注意,当包含ClassFromDll的dll是一个静态库,而不是一个dll,一切工作正常。只有当静态库被更改为dll时,泄漏才开始。
当程序在释放模式下泄漏时,它在delete [] m_arr的调试模式下崩溃。崩溃发生在dbgdel.cpp第52行 - _BLOCK_TYPE_IS_VALID(pHead-> nBlockUse)。



在unix平台上,这个lib也是一个共享库,称为有和没有泄漏。问题可能是与VC编译器?或者也许项目的一些其他设置需要改变?

解决方案


我使用的是VC2003。

这是一个老问题在VC ++关于DLL和对象数组。原因是Microsoft解释的不正确的编译器优化。



http://support.microsoft.com/kb/121216/en-us



更好地使用没有问题的STL容器,因为使用allocator。


I have a code that is leaking on Windows. It runs fine on many unix platforms and the leak only occurs on Windows. The binary consists of exe, 1 dll and 2 static libs. The exe links to both the dll and the static libs, while the static libs link with the dll as well. The leak occurs in the exe code when instead of calling to a vector deleting destructor, for some reason scalar deleting destructor is called. This results in only the first object in the array to be deleted while the rest of the array stays in memory.

The leaking pseudo-code looks like this:

class MyClassFromExe : public MyBaseClassFromDll {
  public:
    ClassFromDll* m_arr;

    MyClassFromExe(unsigned int size)  
    {
      m_arr = new ClassFromDll[size];
    }

    ~MyClassFromExe() 
    {
      delete [] m_arr;
    }
};

void func()
{
  MyClassFromExe obj(3);
}

When func() finishes and the destructor is called I see that only the destructor of the first object in m_arr is called. From debugger I see that this is done from scalar deleting destructor and not from vector deleting destructor. This explains why only the first object is destroyed. What I need to understand is why scalar deleting destructor is called when delete [] is used???

I found this thread - Why is vector deleting destructor being called as a result of a scalar delete?. I followed the suggestions there and made sure that all the modules are compiled with /MD.

Important to notice that when the dll that contains ClassFromDll was a static library and not a dll, everything worked fine. The leak started only when the static library was changed to be a dll. While the program leaks in Release mode, it crashes in Debug mode on delete [] m_arr. The crash occurs in dbgdel.cpp line 52 - _BLOCK_TYPE_IS_VALID(pHead->nBlockUse).

On unix platforms this lib is also a shared lib and as expected vector deleting destructor is called there and there is no leak. Could the problem be with the VC compiler? Or maybe some other settings of the projects need to be changed? I'm using VC2003.

Thank you in advance!

解决方案

This is an old Problem in VC++ regarding DLLs and Object-Arrays. The cause is an incorrect compiler optimization as explained by Microsoft.

http://support.microsoft.com/kb/121216/en-us

Better use the STL-containers which dont have the problem due to the use of allocator.

这篇关于为什么一个标量删除析构函数作为向量删除在Windows上的结果被调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆