why is a scalar deleting destructor being called as a result of vector delete on Windows?

21,510

Solution 1

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.

Solution 2

A class in a DLL is extremely touchy, without much help from compilers. Check out this answer for details WHY this is problematic: How can I call a function of a C++ DLL that accepts a parameter of type stringstream from C#?.

Short version: if the class interface uses ANY inlined code, you will experience potential problems exactly like this. Any templated object (such as std::string) included.

I would guess this is why. It is similar to the problem @Mikael Persson suggests.

Share:
21,510

Related videos on Youtube

noplk
Author by

noplk

Updated on April 17, 2020

Comments

  • noplk
    noplk about 4 years

    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!

  • noplk
    noplk about 13 years
    Thank you for the response. I also suspect that this can be a problem with different heaps of the dll and exe, but I simply don't see how I can get into this problem. Please notice that both new and delete calls are made from the exe. There are no factories used in the actual code, it's pretty identical to what I wrote here. There is no new and delete operator overloading anywhere. All the projects are compiled with /MD. Any suggestions regarding how the allocation and the destruction could be done on different heaps will help greatly.
  • noplk
    noplk about 13 years
    Thanks for providing this link! This confirms that indeed this is a compiler bug.

Related