Why is a scalar deleting a destructor called as a result of vector removal on Windows?

I have code that runs on Windows. It works great on many unix platforms, and the leak only occurs on Windows. The binary file consists of exe, 1 dll and 2 static libs. Exe refers to both dll and static libs, and static libs also refer to DLLs. A leak occurs in exe code, when instead of calling a vector that removes the destructor, scalar destructor removal is called for some reason. This leads to the fact that only the first object in the array will be deleted, and the rest of the array will remain in memory.

Penetrating pseudocode is as follows:

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 () ends and the destructor is called, I see that only the destructor of the first object in m_arr is called. From the debugger, I see that this is done from a scalar destructor deletion, and not from a vector destructor deletion. This explains why only the first object is destroyed. What I need to understand is why scalar destructor deletion is called when using delete [] ???

I found this thread - Why is a vector removing a destructor called as a result of scalar deletion? . I followed the suggestions and made sure that all modules were compiled using / MD.

It is important to note that when the DLL containing ClassFromDll was a static library, not a dll, everything worked fine. The leak started only when the static library was changed as a DLL. While the program runs in Release mode, it shuts down in debug mode when [] m_arr is deleted. The crash occurs on the line dbgdel.cpp 52 - _BLOCK_TYPE_IS_VALID (pHead-> nBlockUse).

On unix platforms, this lib is also a shared lib library and is expected to invoke a vector destructive destructor there, and there is no leak. Could the problem be with the VC compiler? Or maybe some other project settings need to be changed? I am using VC2003.

Thank you in advance!

+6
c ++ debugging vector memory-leaks destructor
source share
5 answers

This is an old problem in VC ++ regarding DLL and Object-Arrays. The reason is incorrect compiler optimization, as explained by Microsoft.

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

It is better to use STL containers that do not have a problem due to the use of a dispenser.

+4
source share

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

Short version: if the class interface uses ANY inline code, you will encounter potential problems in that way. Any template object (e.g. std::string ) is included.

I would suggest that is why. This is similar to the problem posed by @ Michael Persson.

+1
source share

I think this is an obvious case of allocating one heap and deleting it to another (remember that delete [] should request a heap for the number of elements in the array, and if the heap does not even contain this pointer, it will return an "error" (not really), and this is assumed to be just one element and scalar deletion is used instead). I think your problem was lost trying to reduce it to a simple code example. I would advise you to read this article (it is old, but the removal technique is still very relevant, I use a variation of this technique myself, and it works like witchcraft). One of the modern ways to do this is to attach the delete function pointer to the smart pointer (shared_ptr) that processes your object, thus assigning this pointer to the delete function at the same time as creating the object in the factory function will make sure that the delete will be called on the same heap. to which it was allocated.

0
source share

In general, I would recommend using std :: vector <ClassFromDLL> instead of ClassFromDLL *. Build it to fit. Then the removal will be automatic. Unfortunately, I don't have much experience with delete [], because I always let the standard library do this for me; -)

0
source share

Looking at the code, I assume that the object was copied using the default ctor copy, which leads to a double delete error. This is Undefined Behavior. It may seem like it works, but breaks seemingly unrelated changes - ushc like switching from a LIB to a DLL.

0
source share

All Articles