I Do Not Like C++

Hey lazyweb, how do you debug memory leaks in C++?

I’ve hit on a really, really horrible solution, and I’d like an opinion on what I can do instead. All of my objects in my project are subclasses of this class:

typedef const char *ClassName;
struct live_object {
  ClassName isa;
  utime_t created;
};
std::map<void *, live_object> *liveObjects();
class base {
  private:
    const char *isa;
    static void __a(base *ptr) {
      std::map<void *, live_object> *objs = liveObjects();
      std::map<void *, live_object>::iterator it = objs->find(ptr);
      if (it != objs->end())
        (*it).second.isa = ptr->isa;
    }
    static void __d(base *ptr) {
      std::map<void *, live_object> *objs = liveObjects();
      std::map<void *, live_object>::iterator it = objs->find(ptr);
      if (it != objs->end()) {
        log deletion of a class
        objs->erase(it);
      }
    }
  public:
    base(ClassName isa) : isa(isa) { __r(this); }
    base() : isa("UNKNOWN CLASS") { __r(this); }
    virtual ~base() { __d(this); }
    static void *operator new(size_t sz) throw(std::bad_alloc) {
      void *ptr = malloc(sz);
      live_object o;
      o.created = now();
      std::map<void *, live_object> *objs = liveObjects();
      (*objs)[ptr] = o;
      return ptr;
    }
};

And yes, every subclass of this needs to call base("class-name") in the constructor, to get a meaningful name for the class.

I have a periodic event that dumps out all live, dynamically-allocated objects, along with their class name and how long they’ve been alive. It looks like this:

-- BEGIN DUMP OF LIVE OBJECTS --
0x8090d60 -- isa: comms::MethodCall alive for 1200253ms
0x8090ec0 -- isa: util::Authenticator alive for 1200253ms
0x8091f30 -- isa: UNKNOWN CLASS alive for 22017ms
0x8099928 -- isa: UNKNOWN CLASS alive for 19969ms
0x80a4608 -- isa: util::Event alive for 1140090ms
0x80a59c0 -- isa: UNKNOWN CLASS alive for 22017ms
0x80be650 -- isa: HealthReporter alive for 1155229ms
0x80bf608 -- isa: UNKNOWN CLASS alive for 19969ms
0x80e3068 -- isa: UNKNOWN CLASS alive for 19969ms
0x80e6060 -- isa: UNKNOWN CLASS alive for 19969ms
0x80e8550 -- isa: UNKNOWN CLASS alive for 19969ms
-- END DUMP OF LIVE OBJECTS --

Now, this may be useful, but it’s such a pain in the ass to get working; there’s got to be a better way, hasn’t there?

Update: that was easy, I suppose. Valgrind on x86 is awesome, though it gives me a ton of errors I can do nothing about. It turns out I was using a library in the wrong — but, kind of the obvious — way, which was leaking a tiny bit of memory. The program I’m working on is awesome, by the way: it runs lots of different things in one thread, something I’ve wanted to do ever since I’ve had to debug multithreaded programs, but never got the chance to do it right until now.