Singletons & delete error 
Author Message
 Singletons & delete error

The following code works if everything is contained in the
executable.  However, if the Singleton is put in its own
DLL, I have the problem that when I create the Singleton
via a "new Singleton" call in the main routine, the delete
function will cause the function to crash.  Any ideas as
to why?  Note, one can still use the "new" singleton and
have it work, one can just not delete it.

-Jeff

Code was pulled from:
http://www.*-*-*.com/

//---------- the h file ---------------------------------
class Singleton
{
public:
        Singleton();
        virtual ~Singleton() {}
        virtual void Method1() { h.Method1(); }
        virtual int Method2() { return h.Method2(); }
private:
        Singleton& h;  // The handle

Quote:
};

//--------------- The cpp implementation file -----------
#include "Singleton.h"

class SingletonImpl : public Singleton
{
public:
        SingletonImpl() : a1(5) {}
        virtual void Method1();
        virtual int Method2();
        static Singleton& Get();
private:
        int a1;            // implementation details ...
        void Internal2();  // This could be public as well

Quote:
};

Singleton::Singleton()
        : h(SingletonImpl::Get()) {} // Singleton
constructor

// SingletonImpl implementataion
Singleton& SingletonImpl::Get()
{
        static SingletonImpl s;
        return s;

Quote:
}

void SingletonImpl::Method1() { a1 *= 10; }

int SingletonImpl::Method2() { return a1; }

//--------------------- A sample client -------------------
-
#include "Singleton.h"
int main(int argc, char* argv[])
{
        Singleton* s1 = new Singleton;
        Singleton s2;

        s1->Method1();
        printf("Should be 50, %d\n", s2.Method2());
        printf("Should also be 50, %d\n",
                Singleton().Method2());
        delete s1;
        return 0;

Quote:
}        



Sat, 19 Nov 2005 05:37:28 GMT  
 Singletons & delete error
From a first glance, this looks like a memory allocation/deallocation
problem across DLL boundaries. Memory management in Win32 DLLs is a
veritable pain in the ass. But to cut a long story short, to avoid problems,
you need to allocate and deallocate objects implemented in the DLL *in the
context of the DLL itself* (for various reasons, including different heaps,
packing, RTL, etc., some or all of which may or may not apply here).

Normally, this is done by providing factory objects or methods as part of
the object or the DLL, along with matching code that performs deallocation.

class SingletonImpl : public Singleton
{
    .
    .
    .
    static Singleton *Create() { return new Singleton; }
    static void Destroy(Singleton *s) { delete s; }
    .
    .
    .

Quote:
};

This will ensure the object is created and destroyed within the context of
the DLL. Also, your code mixes instantiating DLL-provided objects on your
main process stack with heap-based allocations. Switch to using only the
factory methods above instead.

  -- Dan


Quote:
> The following code works if everything is contained in the
> executable.  However, if the Singleton is put in its own
> DLL, I have the problem that when I create the Singleton
> via a "new Singleton" call in the main routine, the delete
> function will cause the function to crash.  Any ideas as
> to why?  Note, one can still use the "new" singleton and
> have it work, one can just not delete it.

> -Jeff

> Code was pulled from:
> http://www.codeguru.com/mfc/comments/1081.shtml

> //---------- the h file ---------------------------------
> class Singleton
> {
> public:
> Singleton();
> virtual ~Singleton() {}
> virtual void Method1() { h.Method1(); }
> virtual int Method2() { return h.Method2(); }
> private:
> Singleton& h;  // The handle
> };

> //--------------- The cpp implementation file -----------
> #include "Singleton.h"

> class SingletonImpl : public Singleton
> {
> public:
> SingletonImpl() : a1(5) {}
> virtual void Method1();
> virtual int Method2();
> static Singleton& Get();
> private:
> int a1;    // implementation details ...
> void Internal2();  // This could be public as well
> };

> Singleton::Singleton()
> : h(SingletonImpl::Get()) {} // Singleton
> constructor

> // SingletonImpl implementataion
> Singleton& SingletonImpl::Get()
> {
> static SingletonImpl s;
> return s;
> }

> void SingletonImpl::Method1() { a1 *= 10; }

> int SingletonImpl::Method2() { return a1; }

> //--------------------- A sample client -------------------
> -
> #include "Singleton.h"
> int main(int argc, char* argv[])
> {
> Singleton* s1 = new Singleton;
> Singleton s2;

> s1->Method1();
> printf("Should be 50, %d\n", s2.Method2());
> printf("Should also be 50, %d\n",
> Singleton().Method2());
> delete s1;
> return 0;
> }



Sat, 19 Nov 2005 10:46:02 GMT  
 Singletons & delete error

Using Dan's advice will work, but if you can't arrange to match
new/delete calls within the same module (exe/dll), then just ensure
that the modules are all compiled with the same dll-based runtimes,
so all modules will share the same heap (eg, build all modules
to use Release Multithreaded DLL runtime) and the same code
generation options (alignment etc). You cannot use statically linked
runtimes for any module (since that module would then have its own
private heap). If you use exceptions or rtti in any module, they should
be enabled in all modules.

Of course if you are not building all the modules yourself, this may
not be doable.


Quote:
> From a first glance, this looks like a memory allocation/deallocation
> problem across DLL boundaries. Memory management in Win32 DLLs is a
> veritable pain in the ass. But to cut a long story short, to avoid
problems,
> you need to allocate and deallocate objects implemented in the DLL *in the
> context of the DLL itself* (for various reasons, including different
heaps,
> packing, RTL, etc., some or all of which may or may not apply here).

> Normally, this is done by providing factory objects or methods as part of
> the object or the DLL, along with matching code that performs
deallocation.

> class SingletonImpl : public Singleton
> {
>     .
>     .
>     .
>     static Singleton *Create() { return new Singleton; }
>     static void Destroy(Singleton *s) { delete s; }
>     .
>     .
>     .
> };

> This will ensure the object is created and destroyed within the context of
> the DLL. Also, your code mixes instantiating DLL-provided objects on your
> main process stack with heap-based allocations. Switch to using only the
> factory methods above instead.

>   -- Dan



> > The following code works if everything is contained in the
> > executable.  However, if the Singleton is put in its own
> > DLL, I have the problem that when I create the Singleton
> > via a "new Singleton" call in the main routine, the delete
> > function will cause the function to crash.  Any ideas as
> > to why?  Note, one can still use the "new" singleton and
> > have it work, one can just not delete it.

> > -Jeff

> > Code was pulled from:
> > http://www.codeguru.com/mfc/comments/1081.shtml

> > //---------- the h file ---------------------------------
> > class Singleton
> > {
> > public:
> > Singleton();
> > virtual ~Singleton() {}
> > virtual void Method1() { h.Method1(); }
> > virtual int Method2() { return h.Method2(); }
> > private:
> > Singleton& h;  // The handle
> > };

> > //--------------- The cpp implementation file -----------
> > #include "Singleton.h"

> > class SingletonImpl : public Singleton
> > {
> > public:
> > SingletonImpl() : a1(5) {}
> > virtual void Method1();
> > virtual int Method2();
> > static Singleton& Get();
> > private:
> > int a1;    // implementation details ...
> > void Internal2();  // This could be public as well
> > };

> > Singleton::Singleton()
> > : h(SingletonImpl::Get()) {} // Singleton
> > constructor

> > // SingletonImpl implementataion
> > Singleton& SingletonImpl::Get()
> > {
> > static SingletonImpl s;
> > return s;
> > }

> > void SingletonImpl::Method1() { a1 *= 10; }

> > int SingletonImpl::Method2() { return a1; }

> > //--------------------- A sample client -------------------
> > -
> > #include "Singleton.h"
> > int main(int argc, char* argv[])
> > {
> > Singleton* s1 = new Singleton;
> > Singleton s2;

> > s1->Method1();
> > printf("Should be 50, %d\n", s2.Method2());
> > printf("Should also be 50, %d\n",
> > Singleton().Method2());
> > delete s1;
> > return 0;
> > }



Sun, 20 Nov 2005 04:16:25 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. error when using delete & new in class

2. Error Using new & delete in class

3. Singleton not a singleton?

4. ATL Singleton and Singleton Class also from C++

5. CString, char && delete

6. Linker error 2001 @&(#&@#&$@

7. Linker error 2001 @&(#&@#&$@

8. scanf() && printf() error

9. CCmdTarget && delete && CList

10. Singletons & 'Interface Marshalled for a different thread' error

11. Using ADO to create/delete tables & fields

12. ClassWizard deleting my h & cpp files

 

 
Powered by phpBB® Forum Software