Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Any memory leak for this Singleton Implementation

Reply
Thread Tools

Any memory leak for this Singleton Implementation

 
 
tomgee
Guest
Posts: n/a
 
      01-13-2006
I saw it many times,

// T.h:

class T
{
public:
static T* instance();
private:
T() {}
~T() {}
static T* smInstance;
};

// T.cpp:

T* T::smInstance = NULL;

T* T::instance()
{
if (smInstance == NULL)
smInstance = new T();

return smInstance;
}

But I suspected there is a memory leak, because there is a free() call
for the memory allocated by new().

However, I saw it many times that I tend to doubt myself - a similiar
implementation even appears on the "c++ cook book", a very new book by
O'really.

Anybody can help to clarify? Thanks.

 
Reply With Quote
 
 
 
 
mlimber
Guest
Posts: n/a
 
      01-13-2006

tomgee wrote:
> I saw it many times,
>
> // T.h:
>
> class T
> {
> public:
> static T* instance();
> private:
> T() {}
> ~T() {}
> static T* smInstance;
> };
>
> // T.cpp:
>
> T* T::smInstance = NULL;
>
> T* T::instance()
> {
> if (smInstance == NULL)
> smInstance = new T();
>
> return smInstance;
> }
>
> But I suspected there is a memory leak, because there is a free() call
> for the memory allocated by new().
>
> However, I saw it many times that I tend to doubt myself - a similiar
> implementation even appears on the "c++ cook book", a very new book by
> O'really.
>
> Anybody can help to clarify? Thanks.


I think you mean something more like:

template<class T>
class Singleton
{
// ...
};

It's not a memory leak if your program never stops running or if the OS
cleans up after you, one of which is probably true on all modern
systems. See chapter 6 of _Modern C++ Design_ for more than you ever
wanted to know about implementing singletons in C++.

Cheers! --M

 
Reply With Quote
 
 
 
 
tomgee
Guest
Posts: n/a
 
      01-13-2006
No, it's not templated. I am sorry to have used this misleading class
name.

How can you make sure the OS will clean it up, without calling a
free()? Can you please explain a little implementation here, I am only
concerned about the dynamic memory allocation and claiming?

Thanks.

 
Reply With Quote
 
Ben Pope
Guest
Posts: n/a
 
      01-13-2006
tomgee wrote:
> I saw it many times,
>
> // T.h:
>
> class T
> {
> public:
> static T* instance();
> private:
> T() {}
> ~T() {}
> static T* smInstance;
> };
>
> // T.cpp:
>
> T* T::smInstance = NULL;
>
> T* T::instance()
> {
> if (smInstance == NULL)
> smInstance = new T();
>
> return smInstance;
> }
>
> But I suspected there is a memory leak, because there is a free() call
> for the memory allocated by new().


I suspect you meant there is *NO* call to free.

What you *should* have said is that there is no call to delete.

> However, I saw it many times that I tend to doubt myself - a similiar
> implementation even appears on the "c++ cook book", a very new book by
> O'really.
>
> Anybody can help to clarify? Thanks.


When is smInstance deconstructed?

Ben Pope
--
I'm not just a number. To many, I'm known as a string...
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      01-13-2006
tomgee wrote:
> I saw it many times,
>
> // T.h:
>
> class T
> {
> public:
> static T* instance();
> private:
> T() {}
> ~T() {}
> static T* smInstance;
> };
>
> // T.cpp:
>
> T* T::smInstance = NULL;
>
> T* T::instance()
> {
> if (smInstance == NULL)
> smInstance = new T();
>
> return smInstance;
> }


Seems like this 'T' is created once and deleted never.

> But I suspected there is a memory leak, because there is a free() call
> for the memory allocated by new().


Huh? Care to rephrase that?

> However, I saw it many times that I tend to doubt myself - a similiar
> implementation even appears on the "c++ cook book", a very new book by
> O'really.


O'Reilly. Unless you intended a pun (word play on "Oh, really?")

On many modern platforms, when the program ends, all of the memory it
occupied is released. If something is dynamically created and never
destroyed explicitly, it is _quite_possible_ that the memory is still
made available to the system by the system after the program ends. But
you need to consider a couple of other points. First, what if memory
is not released? What if somebody writes a memory management engine
that keeps memory around forever until the user explicitly deletes it?
In that case the rule "always 'delete' what you get from 'new'" has all
the merit it can ever have. Second, what if somebody fixes this code
in such a way that the destructor of the singleton now has side effects?
If you don't explicitly 'delete' the pointer, the side effects will never
take place. And so on...

V
 
Reply With Quote
 
TB
Guest
Posts: n/a
 
      01-13-2006
tomgee sade:
> No, it's not templated. I am sorry to have used this misleading class
> name.
>
> How can you make sure the OS will clean it up, without calling a
> free()? Can you please explain a little implementation here, I am only
> concerned about the dynamic memory allocation and claiming?
>
> Thanks.
>


The OS always reclaims the memory your program allocated upon exit,
wheather you delete'd it or not.

But if you want too, you could delete it yourself when your program
exits:

void foo() {
delete T::instance();
}

#include <cstdlib>

int main() {
std::atexit(&foo);
return 0;
}

TB
 
Reply With Quote
 
tomgee
Guest
Posts: n/a
 
      01-13-2006
Thank you all for the above threads. I was in a hurry and made some
typos and mistakes, but you are smart to understand my question through
all that.

Since "The OS always reclaims the memory your program allocated upon
exit,
wheather you delete'd it or not. ", can I say, generally, memory leak
only happens when the application is running(it keeps asking more
memory without returning), and ends all when it terminates? Well,
Suppose the occasions Victor Bazarov mentioned won't come up.

Thanks

 
Reply With Quote
 
Markus Moll
Guest
Posts: n/a
 
      01-13-2006
Hi

tomgee wrote:

> But I suspected there is a memory leak, because there is a free() call
> for the memory allocated by new().


Well, it's at least bad practice, as I would expect the destructor of the
singleton object to be called before the program exits.

Anyway, I just wanted to add that a solution would be to simply use
std::auto_ptr (making std::auto_ptr friend).

Markus

 
Reply With Quote
 
Jay Nabonne
Guest
Posts: n/a
 
      01-14-2006
On Fri, 13 Jan 2006 12:24:34 -0800, tomgee wrote:

> I saw it many times,
>
> // T.h:
>
> class T
> {
> public:
> static T* instance();
> private:
> T() {}
> ~T() {}
> static T* smInstance;
> };
>
> // T.cpp:
>
> T* T::smInstance = NULL;
>
> T* T::instance()
> {
> if (smInstance == NULL)
> smInstance = new T();
>
> return smInstance;
> }
>
> But I suspected there is a memory leak, because there is a free() call
> for the memory allocated by new().
>


Not only does it leak, but the destructor won't be called.

If you don't use a pointer, you can make it auto-destructing:

class T
{
public:
static T& instance();
private:
T() {}
~T() {}
};

// T.cpp:

T& T::instance()
{
// constructed when first executed. Destructed when program exits.
static T t;

return t;
}

- Jay

 
Reply With Quote
 
Axter
Guest
Posts: n/a
 
      01-14-2006

Victor Bazarov wrote:
> tomgee wrote:
> > I saw it many times,
> >
> > // T.h:
> >
> > class T
> > {
> > public:
> > static T* instance();
> > private:
> > T() {}
> > ~T() {}
> > static T* smInstance;
> > };
> >
> > // T.cpp:
> >
> > T* T::smInstance = NULL;
> >
> > T* T::instance()
> > {
> > if (smInstance == NULL)
> > smInstance = new T();
> >
> > return smInstance;
> > }

>
> Seems like this 'T' is created once and deleted never.
>
> > But I suspected there is a memory leak, because there is a free() call
> > for the memory allocated by new().

>
> Huh? Care to rephrase that?
>
> > However, I saw it many times that I tend to doubt myself - a similiar
> > implementation even appears on the "c++ cook book", a very new book by
> > O'really.

>
> O'Reilly. Unless you intended a pun (word play on "Oh, really?")
>
> On many modern platforms, when the program ends, all of the memory it
> occupied is released. If something is dynamically created and never
> destroyed explicitly, it is _quite_possible_ that the memory is still
> made available to the system by the system after the program ends. But
> you need to consider a couple of other points. First, what if memory
> is not released? What if somebody writes a memory management engine
> that keeps memory around forever until the user explicitly deletes it?
> In that case the rule "always 'delete' what you get from 'new'" has all
> the merit it can ever have. Second, what if somebody fixes this code
> in such a way that the destructor of the singleton now has side effects?
> If you don't explicitly 'delete' the pointer, the side effects will never
> take place. And so on...
>


Having a singleton get explicitly deleted can cause more harm then
good, if it's called from a destructor of multiple global objects.

If you try to delete it in main, then your global objects will be
calling a deleted object, and at best, it will result in undefined
behavior, and at worse crash the program.

So it's not ALWAYS preferable to have a singleton get explicitly
deleted, and that's why you'll commonly find singleton implementation
that never calls the destructor.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Singleton object vs. enhancing singleton class Paul McMahon Ruby 3 06-09-2008 06:05 AM
Singleton Modules rather than Singleton Classes Trans Ruby 12 09-14-2007 06:45 AM
Singleton - Whether Cloneable overrides Singleton Proton Projects - Moin Java 4 03-27-2007 02:59 AM
501 PIX "deny any any" "allow any any" Any Anybody? Networking Student Cisco 4 11-16-2006 10:40 PM
Singleton classes and Singleton pattern Wilhelm Ruby 1 10-11-2006 01:08 PM



Advertisments