あおきです。 In mail "[ruby-ext:00691] Re: (gtk) testgtk/ctree" Yasushi Shoji <yashi / yashi.com> wrote: > やすしです。 > 自分の落ちる(落ちた)原因の解釈としては > > row.dataに渡された Ruby objectへ GCの root([ruby-dev: 3527]参照)から、再 > 帰的にたぐれなくなったために(cの stackから消えたから?)、memoryが解放され > る。その後、row.dataを accessしたときに落ちる。 > > で、nodeを解放するときに、row.dataが Ruby objectの場合、row.destroy == > NULL にしておいても、Ruby objectは GCの対象になる(hashなどからの参照も消 > えれば)ので、ほっといても leakしない。 > > なのですが、どこで勘違いしてるのでしょうか? > # rb_gc_mark()は、objectに markを付けて、sweepの対象外にする? そうです。 Rubyは生成したオブジェクトを全部知っていて、そのなかの生きていることが 確実なオブジェクトから再帰的にポインタをたどり、生きオブジェクトを 探索します。マーク関数は、Rubyが知らない構造体の中にある VALUE を 教えてやるために使われます。 つまり、マーク関数が呼ばれた時点で、ruby-gtk オブジェクトは生きていた (Rubyから参照している)ことは確実です。つまり、そのマーク関数でマーク している row.data も Ruby からは直接、間接に参照されており、 これまでには解放されていないはずです。 また、Gtk 側からも直接 row.data を解放したりはしないので (Gtkには解放の仕方がわからないから当然)、row.data はまだ生きているはずです。 つまり、落ちるのは row.data 自体を触ったからではないと言えます。 で、実際に試してみると、なんとNULLになってたのは GTK_CTREE_ROW(node)でした。 node と GTK_CTREE_ROW(node) は全然別物、というとこがポイントです。 ^^^^ ^^^ (つまり、ぼくの前回の解釈もやはり間違っている。) 結局、最終的な解決方法は以下のようになりました。 # 五十嵐さん何度もごめんなさい (__);; ------------------------------------------------------------------- あおきみねろう --- org.ctree Fri Dec 3 17:42:17 1999 +++ rbgtkctree.c Fri Dec 10 19:46:33 1999 @@ -6,8 +6,10 @@ ctree_node_mark(node) GtkCTreeNode *node; { - if (GTK_CTREE_ROW(node) && GTK_CTREE_ROW(node)->row.data) - rb_gc_mark(GTK_CTREE_ROW(node)->row.data); + if (node) + if (GTK_CTREE_ROW(node)) + if (GTK_CTREE_ROW(node)->row.data) + rb_gc_mark(GTK_CTREE_ROW(node)->row.data); } VALUE