師星です。

> Gtk::CTreeでGCのmark中にときたまsegmentation faultを起こす件と、
> Gtk::CListにset_row_dataしたオブジェクトが該当rowの削除後もCList本体の解
> 放までGCされない件を修正するパッチを作りました。

このパッチのCTree部分にバグがありました。

> 結局、CTreeの方ではこの関数をそのまま流用して同じようなインスタンス変数
> を持たせるだけで済みました。

これは勘違いで、これだとshrinkされているノードのrow_dataがマークされてい
ませんでした。
# 再帰をループで済ませられれば安上がりと思って失念していました

前のものの代わりに以下をお試し下さい。
--
MOROHOSHI Akihiko

diff -urN -x *.orig -x *.bak -x *~ gtk-0.23.orig/src/rbgtkclist.c gtk-0.23.new/src/rbgtkclist.c --- gtk-0.23.orig/src/rbgtkclist.c Sat Jan 8 20:52:28 2000 +++ gtk-0.23.new/src/rbgtkclist.c Wed Oct 4 16:04:34 2000 @@ -13,9 +13,29 @@ #include "global.h" +static ID id_marker; + /* * CList */ + +static void +clist_marker_mark(clist) + GtkCList *clist; +{ + if (clist) { + GList *list; + for (list = clist->row_list; list; list=list->next) { + if (list->data) { + GtkCListRow *row = GTK_CLIST_ROW(list); + if (row->data) { + rb_gc_mark_maybe(row->data); + } + } + } + } +} + static VALUE clist_initialize(self, titles) VALUE self, titles; @@ -38,6 +58,8 @@ widget = gtk_clist_new(NUM2INT(titles)); } set_widget(self, widget); + rb_ivar_set(self, id_marker, Data_Wrap_Struct(rb_cData, clist_marker_mark, + 0, widget)); return Qnil; } @@ -438,7 +460,6 @@ clist_set_row_data(self, row, data) VALUE self, row, data; { - add_relative(self, data); gtk_clist_set_row_data(GTK_CLIST(get_widget(self)), NUM2INT(row), (gpointer)data); return self; @@ -649,6 +670,8 @@ { gCList = rb_define_class_under(mGtk, "CList", gContainer); + id_marker = rb_intern("marker"); + /* Signals */ rb_define_const(gCList, "SIGNAL_SELECT_ROW", rb_str_new2("select_row")); rb_define_const(gCList, "SIGNAL_UNSELECT_ROW", rb_str_new2("unselect_row")); diff -urN -x *.orig -x *.bak -x *~ gtk-0.23.orig/src/rbgtkctree.c gtk-0.23.new/src/rbgtkctree.c --- gtk-0.23.orig/src/rbgtkctree.c Sat Jan 8 20:52:29 2000 +++ gtk-0.23.new/src/rbgtkctree.c Wed Oct 4 16:09:35 2000 @@ -14,15 +14,38 @@ #include "global.h" static ID id_nodelist; +static ID id_marker; static void -ctree_node_mark(node) +ctree_node_mark_recursive(node) GtkCTreeNode *node; { - if (node) - if (GTK_CTREE_ROW(node)) - if (GTK_CTREE_ROW(node)->row.data) - rb_gc_mark_maybe(GTK_CTREE_ROW(node)->row.data); + if (node) { + GtkCTreeRow *row = GTK_CTREE_ROW(node); + if (row) { + GtkCTreeNode *work; + + if (row->row.data) + rb_gc_mark_maybe(row->row.data); + + for (work=row->children; work; work=GTK_CTREE_NODE_NEXT(work)) + ctree_node_mark_recursive(work); + } + } +} + +static void +ctree_marker_mark(ctree) + GtkCTree *ctree; +{ + if (ctree) { + GtkCTreeNode *work; + work = gtk_ctree_node_nth(ctree, 0); + while (work) { + ctree_node_mark_recursive(work); + work = GTK_CTREE_NODE_NEXT(work); + } + } } VALUE @@ -30,7 +53,7 @@ GtkCTreeNode* node; { if (!node) return Qnil; - return Data_Wrap_Struct(gCTreeNode, ctree_node_mark, 0, node); + return Data_Wrap_Struct(gCTreeNode, 0, 0, node); } static GtkCTreeNode* @@ -87,6 +110,8 @@ nodelist = rb_ary_new(); rb_ivar_set(self, id_nodelist, nodelist); + rb_ivar_set(self, id_marker, Data_Wrap_Struct(rb_cData, ctree_marker_mark, + 0, widget)); return Qnil; } @@ -1425,6 +1450,7 @@ gCTreeNode = rb_define_class_under(mGtk, "CTreeNode", rb_cData); id_nodelist = rb_intern("nodelist"); + id_marker = rb_intern("marker"); /* constants */