Boost logo

Boost Users :

From: Joshua Little (ljoshua_at_[hidden])
Date: 2004-02-14 15:24:26


Hi again,
Well I'm making pretty good progress in learning proper way to use
shared_ptr's but I'm still a little nervous about leaking memory,
especially if I manage to do something I'm not supposed to do and don't
recognize that a memory leak may be occuring. I've used the overloading
new/delete before to help track memory leaks and I was wondering if that
would be possible with shared_ptrs.
I tried my old header files with and saw tons of leaks but I think its
because my New that I use logs the creation to a Tracer class but since
the Delete happens in the shared_ptr, its not using the overloaded
Delete that removes stuff from the tracer when its deleted.
I've looked around and found some examples of making a custom deleter to
pass into the shared ptr when creating a new shared_ptr which should
work but I have some worries about it. I'm not quite sure what the
recommended way of doing this would be. About the only thing I can think
of would be to have two different deleters which would be conditionally
compiled something like this :

//Overloaded New to log allocation to a tracer, theres a define to add
the file and line number to the new call
#ifndef NDEBUG
void * operator new (unsigned int size, char const * file, int line)
{
    void * p = new (size);
    if (Tracer::Ready)
        NewTrace.Add (p, file, line);
    return p;
}

struct deleter {
    void operator() (void * p) const {
          if (Tracer::Ready)
              NewTrace.Remove(p);
               delete p;
    }
 }
#else
struct deleter {
    void operator() (void * p) const {
               delete p;
    }
 }
#endif
//NewTrace is an extern'd object in the Main.cpp file
So then I'd pass in the deleter to the shared_ptr and then whichever
deleter was defined would be passed into the shared_ptr.
I'm kinda cobbling together a few different things I've seen but I think
that with this I could include the header file in the .cpp file of any
class that I want to track the memory of and then just make sure I send
in the deleter when I reset or make a new shared ptr.
For instance in my LoggerFactory.cpp file :
#include "../include/Logger.hpp"
#include "../include/LoggerFactory.hpp"
#include "../include/dbnew.hpp"

LoggerMap LoggerFactory::loggers;

boost::shared_ptr<Logger> LoggerFactory::getInstance(std::string& logger) {
 boost::shared_ptr<Logger>& TheLoggerRef = loggers[logger];
  if(!TheLoggerRef.get())
    TheLoggerRef.reset(new Logger(logger),deleter());
  return TheLoggerRef;
}

So then the dbnew would define the deleter to use for the Logger object,
if it was a debug build it would also create the overloaded new
operator, define the _FILE_ and _LINE_ macros to send into the new New
operator. And if its not the debug build then essentially the normal
deleter is given to the shared_ptr and everything procedes as normal.
Is this a good way to go about adding memory leak checking? I've looked
for a new memory leak checkers like valgrind but thats only available on
Linux and I'm stuck on windows.. and all the memory checkers I've been
able to find only support VC++ or borland and I use gcc. So I would like
a nice simple way that I can drop right in, which is what I'm going for
with the overloading new and the custom deleter.
Joshua.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net