[cairo] Memory leaks in cairomm

Rodrigo Rivas rodrigorivascosta at gmail.com
Mon Jun 12 07:41:37 PDT 2006

I don't know if I'm missing something, but I've noted that the RefPtr
implementation in cairomm leaks memory "always".
That is because when you call, say Surface::create(...), it calls
basically "new Surface(cairo_surface_create_linear(...))" and returns
the new pointer wrapped into a RefPtr<Surface>. The ~RefPtr decrements
the ref-counter of the cairo_surface_t object, but it <never> deletes
the new'ed Surface object. It's same for every type in cairomm.
The glibmm's RefPtr doesn't leak! But that's because the
Glib::ObjectBase class takes care of this, and gets notified when the
wrapped object is destroyed.
Also there are a few Glib classes that doesn't inherit from
Glib::ObjectBase, such as Glib::Thread. Those are implemented simple
as cast pointers to the underlying type (I'm not sure this is 100%
portable, valid C++ code, but it will probably work as long as there
is no virtual functions and no member variables).

I've taken this last technique and it looks like this:

class Surface
private:  // no create, no copy, no destroy
  Surface(const Surface&);
  void operator=(const Surface&);

  typedef cairo_surface_t cobject;
  static RefPtr<Surface> wrap(cobject *obj)
    Surface *obj = reinterpret_cast<Surface*>(obj);
    RefPtr<Surface> ptr(obj);
    return ptr;

  static RefPtr<Surface> create(const RefPtr<Surface> other, Content
content, int width, int height)
    cairo_surface_t* cobject = cairo_surface_create_similar(other->cobj(),
                       (cairo_content_t)content, width, height);
    return wrap(cobject);
  cobject* cobj() { return reinterpret_cast<cobject*>(this); }
  cobject* cobj() const { return
const_cast<cobject*>(reinterpret_cast<const cobject*>(this)); } // it
is nonsense to return a const cobject* here

   // the rest of the class is the same

Now, you'll just need to make the same change on ALL the wrapping classes.

Best regards.

More information about the cairo mailing list