not important at all - memory leak

G

Grahamo

Hey,

this is related to absolutely nothing in particular and is of no
importance whatsoever except for my curiousity.

Does anybody have an example of a particularly tricky memory leak
that's hard to spot. I'd like to see something that's a little unusual
or obscure. something that involves some in depth knowledge about
functionality X or scenario X and that causes a memory leak. Something
that would be really easy to miss.

This is simply for curiousity sake and nothing more. if anybody has a
little code snippit or example I'd love to see it

cheers

G
 
A

Axter

Hey,

this is related to absolutely nothing in particular and is of no
importance whatsoever except for my curiousity.

Does anybody have an example of a particularly tricky memory leak
that's hard to spot. I'd like to see something that's a little unusual
or obscure. something that involves some in depth knowledge about
functionality X or scenario X and that causes a memory leak. Something
that would be really easy to miss.

This is simply for curiousity sake and nothing more. if anybody has a
little code snippit or example I'd love to see it

cheers

G

Mixing allocators with wrong deallocators can be easy to miss. (new[]
with delete), (new with delete[]), (new with free), etc....

Example:
int *i = new int(123); //This does NOT create an array
delete[] i; //Wrong deallocator
 
G

Grahamo

thanks, nice start. I would have spotted that one. I'm after one I
would NOT have spotted.... a really tricky one. Thanks though, I'm
compiling a list.

(non) virtual destructors in base classes is a good one, I already have
that.

any others...not run of the mill stuff.


cheers

Graham
 
J

Jonathan Mcdougall

Hey,

this is related to absolutely nothing in particular and is of no
importance whatsoever except for my curiousity.

Does anybody have an example of a particularly tricky memory leak
that's hard to spot. I'd like to see something that's a little unusual
or obscure. something that involves some in depth knowledge about
functionality X or scenario X and that causes a memory leak. Something
that would be really easy to miss.

This is simply for curiousity sake and nothing more. if anybody has a
little code snippit or example I'd love to see it

Well, ADL can change the meaning of a function call silently:

namespace N
{
class C{};

void f(C c, int i)
{
// deletes things
}
}

int main()
{
N::C c;
f(c, 1.0); // may give a conversion warning
}

Adding the global function

void f(C c, double d);

changes the meaning of the call to f(). If N::f() was in charge of
deleting things, you may be suprised.


Jonathan
 
J

John Harrison

Hey,

this is related to absolutely nothing in particular and is of no
importance whatsoever except for my curiousity.

Does anybody have an example of a particularly tricky memory leak
that's hard to spot. I'd like to see something that's a little unusual
or obscure. something that involves some in depth knowledge about
functionality X or scenario X and that causes a memory leak. Something
that would be really easy to miss.

This is simply for curiousity sake and nothing more. if anybody has a
little code snippit or example I'd love to see it

cheers

G

How about this

class Dodgy
{
Dodgy() : ptr(new char[99]) {}
~Dodgy() { delete[] ptr; }
char* ptr;
X x;
};

If the X constructor throws an exception then the memory allocated will
never get freed, even through the destructor does free the memory. This
is because in this case the destructor for Dodgy is never called.

john
 
J

John Harrison

thanks, nice start. I would have spotted that one. I'm after one I
would NOT have spotted.... a really tricky one. Thanks though, I'm
compiling a list.

(non) virtual destructors in base classes is a good one, I already have
that.

any others...not run of the mill stuff.


cheers

Graham

Niether of your two exmaples are memory leaks, they are undefined
behaviour. A memory leak is one possibility but not the only one (or
even the most likely one).

john
 
G

Grahamo

thanks for that... undefined behaviour is ok too. Good point though...
I've noted that point.

cheers


G
 
J

John Harrison

John said:
Hey,

this is related to absolutely nothing in particular and is of no
importance whatsoever except for my curiousity.

Does anybody have an example of a particularly tricky memory leak
that's hard to spot. I'd like to see something that's a little unusual
or obscure. something that involves some in depth knowledge about
functionality X or scenario X and that causes a memory leak. Something
that would be really easy to miss.

This is simply for curiousity sake and nothing more. if anybody has a
little code snippit or example I'd love to see it

cheers

G

How about this

class Dodgy
{
Dodgy() : ptr(new char[99]) {}
~Dodgy() { delete[] ptr; }
char* ptr;
X x;
};

If the X constructor throws an exception then the memory allocated will
never get freed, even through the destructor does free the memory. This
is because in this case the destructor for Dodgy is never called.

john

But this version is OK

class NotDodgy
{
NotDodgy() : ptr(new char[99]) {}
~NotDodgy() { delete[] ptr; }
X x;
char* ptr;
};

No memory leaks there.

john
 
J

John Harrison


The difference is the order of construction. If the X constructor is
called after the allocation of memory and the X constructor throws then
you have a memory leak. But in the second example the X constructor is
called before the memory allocation (because of the different order of
declarations) therefore when the X constructor throws the memory
allocation hasn't happened yet.

john
 
G

Greg

John said:
John said:
Hey,

this is related to absolutely nothing in particular and is of no
importance whatsoever except for my curiousity.

Does anybody have an example of a particularly tricky memory leak
that's hard to spot. I'd like to see something that's a little unusual
or obscure. something that involves some in depth knowledge about
functionality X or scenario X and that causes a memory leak. Something
that would be really easy to miss.

This is simply for curiousity sake and nothing more. if anybody has a
little code snippit or example I'd love to see it

cheers

G

How about this

class Dodgy
{
Dodgy() : ptr(new char[99]) {}
~Dodgy() { delete[] ptr; }
char* ptr;
X x;
};

If the X constructor throws an exception then the memory allocated will
never get freed, even through the destructor does free the memory. This
is because in this case the destructor for Dodgy is never called.

john

But this version is OK

class NotDodgy
{
NotDodgy() : ptr(new char[99]) {}
~NotDodgy() { delete[] ptr; }
X x;
char* ptr;
};

No memory leaks there.

I would note that this example is for illustrative purposes only, no
actual program would rely on something as fragile as the order of
member declarations. Such a requirement is too easy to overlook and too
fragile to maintain.

In the real world, NotDodgy would use a "smart" pointer to manage ptr's
allocation. A smart pointer would ensure that ptr's memory is properly
deallocated should it have been allocated before the exception was
thrown.

Greg
 
J

John Harrison

Greg said:
John said:
John said:
(e-mail address removed) wrote:


Hey,

this is related to absolutely nothing in particular and is of no
importance whatsoever except for my curiousity.

Does anybody have an example of a particularly tricky memory leak
that's hard to spot. I'd like to see something that's a little unusual
or obscure. something that involves some in depth knowledge about
functionality X or scenario X and that causes a memory leak. Something
that would be really easy to miss.

This is simply for curiousity sake and nothing more. if anybody has a
little code snippit or example I'd love to see it

cheers

G


How about this

class Dodgy
{
Dodgy() : ptr(new char[99]) {}
~Dodgy() { delete[] ptr; }
char* ptr;
X x;
};

If the X constructor throws an exception then the memory allocated will
never get freed, even through the destructor does free the memory. This
is because in this case the destructor for Dodgy is never called.

john

But this version is OK

class NotDodgy
{
NotDodgy() : ptr(new char[99]) {}
~NotDodgy() { delete[] ptr; }
X x;
char* ptr;
};

No memory leaks there.


I would note that this example is for illustrative purposes only, no
actual program would rely on something as fragile as the order of
member declarations. Such a requirement is too easy to overlook and too
fragile to maintain.

Absolutely, but Graham was looking for 'a particularly tricky memory
leak that's hard to spot', 'something that's a little unusual
or obscure' and 'Something that would be really easy to miss'.

Making pointer code exception safe is tricky. Another reason not to use
pointers of course. If I had to use pointers for some reason then I
would allocate memory in the body of the constructor.

class Safe
{
Safe() : ptr(0) { ptr = new char[99]; }
~Safe() { delete[] ptr; }
X x;
char* ptr;
};

This code will not leak memory irrespective of initialisation order issues.

john
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,432
Messages
2,571,681
Members
48,796
Latest member
Greg L.

Latest Threads

Top