473,378 Members | 1,138 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,378 software developers and data experts.

Any memory leak for this Singleton Implementation

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.

Jan 13 '06 #1
11 3124

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

Jan 13 '06 #2
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.

Jan 13 '06 #3
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...
Jan 13 '06 #4
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
Jan 13 '06 #5
TB
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
Jan 13 '06 #6
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

Jan 13 '06 #7
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

Jan 13 '06 #8
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

Jan 14 '06 #9

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.

Jan 14 '06 #10

Jay Nabonne wrote:
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;
}


If you use the above method, and the singleton gets called by a global
object's destructor that's in a different translation unit, it will
result in undefined behavior, because there's no garantee of the order
of destruction for global objects in multiple translation units, IAW
C++ standards.

If the singleton is not called from any global object's destructor,
then the above implementation would be the safer and cleaner method.

Jan 14 '06 #11
On 13 Jan 2006 23:48:51 -0800, "Axter" <go****@axter.com> wrote:
If you use the above method, and the singleton gets called by a global
object's destructor that's in a different translation unit, it will
result in undefined behavior, because there's no garantee of the order
of destruction for global objects in multiple translation units, IAW
C++ standards.

If the singleton is not called from any global object's destructor,
then the above implementation would be the safer and cleaner method.


Thank you. That is the first rational explanation that I can
*remember* to counter all the hand-wringing that goes with
Singletons. Mind you, I have felt queasy at times relying on an
unreliable OS to clean up myself. "But we have deadlines to
meet dammit." :-) It's always a balance.

I've used them for years with no trouble except the angst from other
engineers. I've used them to help get younger engineers design's
up and running quickly.

I'll 'nick' the above if you don't mind. :-)
Jan 14 '06 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Jeremy Lemaire | last post by:
Hello, I am working on cross platform code that is displaying a huge memory leak when compiled on 11.00 HPUX using the aCC -AA flag. It is not leaking on NT, LINUX, Solaris, or HPUX without the...
1
by: Spur | last post by:
Hi all, I implemented a memory allocation/deallocation class that logs all new/delete calls (overloaded) and remembers for each allocated block where it was allocated from (using a macro that...
7
by: Ethan | last post by:
Hi, I have a class defined as a "Singleton" (Design Pattern). The codes are attached below. My questions are: 1. Does it has mem leak? If no, when did the destructor called? If yes, how can I...
31
by: William Stacey [MVP] | last post by:
Here is an interesting writing on memory barriers. Not sure if this helps my understanding or raises more questions, but interesting... ...
7
by: Salvador | last post by:
Hi, I am using WMI to gather information about different computers (using win2K and win 2K3), checking common classes and also WMI load balance. My application runs every 1 minute and reports...
8
by: vidya.bhagwath | last post by:
Hello Experts, I am using std::string object as a member variable in one of the my class. The same class member function operates on the std::string object and it appends some string to that...
24
by: c language | last post by:
Hello all, I am using 'Valgrind' to fix the memory leaks of my programs. I am looking for other programs to see how they are detecting the problems. Does any of you have experience in working...
9
by: jeungster | last post by:
Hello, I'm trying to track down a memory issue with a C++ application that I'm working on: In a nutshell, the resident memory usage of my program continues to grow as the program runs. It...
16
by: graham.keellings | last post by:
hi, I'm looking for an open source memory pool. It's for use on an embedded system, if that makes any difference. Something with garbage collection/defragmentation would be nice. It should have...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.