The guys from Gtkmm are comparing Glib::RefPtr
with std::auto_ptr<>
:
Glib::RefPtr
is a smartpointer. Specifically, it is a reference-counting smartpointer. You might be familiar withstd::auto_ptr<>
, which is also a smartpointer, butGlib::RefPtr<>
is much simpler, and more useful.
But for some strange reason, I can't get my work done with the RefPtr
. The same code is just fine with a auto_ptr
.
In the following code, SmartPtr
is just a placeholder for one of these two smartpointers.
#include <gtkmm.h>
#include <iostream>
#include <tr1/memory>
struct WindowHolder {
SmartPtr<Gtk::Window> ptr;
WindowHolder()
: ptr(new Gtk::Window)
{
ptr->signal_delete_event().connect(sigc::mem_fun(*this, &WindowHolder::reset));
ptr->show_all();
}
bool reset(GdkEventAny* event)
{
Gtk::Main::quit();
}
};
int main(int argc, char *argv[])
{
Gtk::Main kit(argc, argv);
WindowHolder w;
kit.run();
}
When compiling, I first define SmartPtr
as Glib::RefPtr
and then as std::auto_ptr
.
$ g++ '-DSmartPtr=Glib::RefPtr' `pkg-config --cflags --libs gtkmm-3.0` main.cc && ./a.out
(main:22093): GLib-GObject-CRITICAL **: g_object_unref: assertion `G_IS_OBJECT (object)' failed
$ g++ '-DSmartPtr=std::auto_ptr' `pkg-config --cflags --libs gtkmm-3.0` main.cc && ./a.out
$
The problem is this GLib-GObject-CRITICAL
. In my real application, this isn't just a single line but a whole bunch of them. In the second version with std::auto_ptr
everything gets destructed well.
Strange enough the code it is just fine in GTK 2:
$ g++ '-DSmartPtr=Glib::RefPtr' `pkg-config --cflags --libs gtkmm-2.4` main.cc && ./a.out
$
I don't want to depend on std::auto_ptr
because it is deprecated and I also don't want to work with a raw pointer because then the destructors have to manually delete the pointers which adds extra complexity ...
My questions are:
Glib::RefPtr
this "critical warning" (probably a double free)?Glib::RefPtr
and gtkmm 3.0?Glib::RefPtr is not meant to be for general use. You should use it when the API forces you to, but not otherwise. GtkWindow (or Gtk::Window) has its own odd memory management which is not really compatible with RefPtr.
If you want a general purpose smartpointer, try std::shared_ptr or std::unique_ptr. Or you could find something in boost.
The reference count is too low, and you can fix it by adding a ptr->reference()
after ptr->show_all()
. I have an explanation, but take it with a grain of salt:
I can't really answer #2 or #4 unfortunately, as this area of gtk/gtkmm is still a little mysterious (to me).
Reference: http://www.gtkforums.com/viewtopic.php?t=2412
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With