GLIB - gnode.c - g_node_destroy(): Feature or error?



First: Sorry for my long mail.

In a program I wrote I start at the leaf and delete nodes (maybe) down
to the root (depends on the node data). So it happend that at the end of
my subroutine when I destroy the tree, I deleted the root node twice
which could result (glib-1.2.7 or glib-1.2.8, gcc 2.95.2, SuSE 6.4) that
my Window Manager gets killed. The error can be reproduced by the
following program:
<----------------- SNIPE ------------------------->
#include <glib.h>
int main(int argc, char** argv){
	GNode	* root=NULL;
	GNode	* tree=NULL;
	gint	* data;
	
	data		=	g_new(gint,1);
	*data		=	1;
	
	root	=	g_node_new(data);
	g_print("root       : %d\n",(gint)* (gpointer *)(root->data));
	
	data		=	g_new(gint,1);
	*data		=	2;
	tree	=	g_node_append_data(root,data);	
	g_print("1st sibling: %d\n",(gint)* (gpointer *)tree->data);
	
	data		=	g_new(gint,1);
	*data		=	3;
	tree	=	g_node_append_data(root,data);	
	g_print("2nd sibling: %d\n",(gint)* (gpointer *)tree->data);

	data		=	g_new(gint,1);
	*data		=	3;
	tree	=	g_node_append_data(tree,data);	
	g_print("1st node of 2nd sibling: %d\n",(gint)* (gpointer
*)tree->data);
	
	g_node_destroy(root);
	g_node_destroy(root);

	return 0;
}
<----------------------SNIPE--------------------->
(The tree has to have at least a depth of 3).
This bad behavior can prevented if g_node_destroy in gnode.c is changed
a little bit:
<----------------------SNIPE--------------------->
void
g_node_destroy (GNode *root)
{
  g_return_if_fail (root != NULL);
  
  if (!G_NODE_IS_ROOT (root))
    g_node_unlink (root);
  
  g_nodes_free (root);
  /* Introduced new line From here --*/
  root->children=NULL;
  /* -- till here */
}
<----------------------SNIPE--------------------->
So - It is probably bad programming style to delete the root node twice,
but if glib could crash under such circumstances a user session....

If glib is changed according to my suggestion there is still an other
problem. If the root node is destroyed twice there are two copies of the
root node memory adresse in the  gnodes 'current_allocator' data
structure. If later two new GNodes are fetched (g_node_new), you get
twice the same memory adresse. 

I changed now my subs for better programming style but maybe you would
like to know this ...

Tobias




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]