简体   繁体   中英

Virtual Destructor causes Access Violation

I am trying to make a DLL file compatible with different compiler configurations (Debug, Release,..). In order to make sure that an object is removed the right way I managed to write a pointer wrapper class that uses a compiled delete operator whenever I take an object of the DLL and run out of scope.

I am perfectly fine with this but my program crashes when I try to delete memory that I allocated in the very same method/program.

Here is some sample code compiled in a standard Release mode:

header

template <typename T>
class API mwCompatibleObject
{
public:

    //! Constructor
    mwCompatibleObject();

    //! Destructor
    virtual ~mwCompatibleObject();
};

source code

template < typename T >
mwCompatibleObject< T >::mwCompatibleObject() {}

template <typename T>
mwCompatibleObject<T>::~mwCompatibleObject() {}

Note: API is defined as export/import.

Now I use this very class in a Debug mode application where I create an instance and delete it right away.

mwCompatibleObject<double> * obj = new mwCompatibleObject<double>();
delete obj;

Executing the delete operator gives an access violation at mlock.c line 376.

Here is a copy of the callstack:

ntdll.dll!7721e3be()    
[Frames below may be incorrect and/or missing, no symbols loaded for ntdll.dll]
msvcr80d.dll!_unlock(int locknum=4)  Line 376   C
msvcr80d.dll!_heap_alloc_dbg(unsigned int nSize=0, int nBlockUse=2968120, const char * szFileName=0x2e2ed26c, int nLine=1638180)  Line 477 + 0x7 bytes  C++
msvcr80d.dll!_heap_alloc_dbg(unsigned int nSize=0, int nBlockUse=2968120, const char * szFileName=0x2e2ed26c, int nLine=1638180)  Line 474 + 0xc bytes  C++
00300000()  
msvcr80d.dll!malloc(unsigned int nSize=2968120)  Line 154 + 0x15 bytes  C++
5axutil.dll!100b5d09()  
Integrator3.exe!main()  Line 54 + 0x34 bytes    C++

I can't jump into that line or anything but I managed to get a look at the Assembler code which proves my observation that it has to do with the destructor.

Is there a general problem with virtual functions/destructors when trying to make a DLL compatible?

You can't export a template definition as the compiler generates the types based on usage of the template. You simply inline them in the header file or you can do something like this but that requires declaring your template instantiation upfront.

Also note in C++ prefer new and delete over malloc and free functions from C especially if you actually want constructors and destructors to be called.

Edit:

I would seriously consider inlining of the template preferable to any attempt to export. Also I failed to note originally that virtual destructors are only needed if your class will be a base class or contain virtual methods. Why have a vtable with nothing in it?

template <typename T>
class mwCompatibleObject // no need for export if inlined in header
{
public:
    //! Constructor
    mwCompatibleObject() {}
    //! Destructor (don't need virtual unless it's a base class or has virtual methods)
    ~mwCompatibleObject() {}

    //! Some public method
    void DoSomething(const T& withSomething)
    {
        // ... yata yata
    }
private:
    T m_member;
};

Further Edit:

I just found out that exporting template support will be completely removed (not deprecated, removed) from the new C++ standard when it is finalized. Inline templates in header files will be the only solution that compilers will implement and allow in the very near future, so get used to writing them this way now. See Herb Sutter's Questions & Answers about C++0x

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM