diff --git a/ChangeLog b/ChangeLog index d0f7ee828..072ce0a4d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2006-01-20 Elijah Newren + + Patch from Søren to fix some reading-from-free'd-data errors. + #327575 + + * src/edge-resistance.c (meta_display_cleanup_edges): store the + edges in a hash table so that we can still read their values + within the loop from the other array they are stored in, then free + them all at the end. + 2006-01-20 Elijah Newren Fix various initialization and default issues, especially for diff --git a/src/edge-resistance.c b/src/edge-resistance.c index 755f2a817..b1eaadd15 100644 --- a/src/edge-resistance.c +++ b/src/edge-resistance.c @@ -646,10 +646,13 @@ meta_display_cleanup_edges (MetaDisplay *display) { guint i,j; MetaEdgeResistanceData *edge_data = display->grab_edge_resistance_data; + GHashTable *edges_to_be_freed; g_assert (edge_data != NULL); /* We first need to clean out any window edges */ + edges_to_be_freed = g_hash_table_new_full (g_direct_hash, g_direct_equal, + g_free, NULL); for (i = 0; i < 4; i++) { GArray *tmp = NULL; @@ -681,15 +684,29 @@ meta_display_cleanup_edges (MetaDisplay *display) MetaEdge *edge = g_array_index (tmp, MetaEdge*, j); if (edge->edge_type == META_EDGE_WINDOW && edge->side_type == dir) - g_free (edge); + { + /* The same edge will appear in two arrays, and we can't free + * it yet we still need to compare edge->side_type for the other + * array that it is in. So store it in a hash table for later + * freeing. Could also do this in a simple linked list. + */ + g_hash_table_insert (edges_to_be_freed, edge, edge); + } } } + /* Now free all the window edges (the key destroy function is g_free) */ + g_hash_table_destroy (edges_to_be_freed); + /* Now free the arrays and data */ g_array_free (edge_data->left_edges, TRUE); g_array_free (edge_data->right_edges, TRUE); g_array_free (edge_data->top_edges, TRUE); g_array_free (edge_data->bottom_edges, TRUE); + edge_data->left_edges = NULL; + edge_data->right_edges = NULL; + edge_data->top_edges = NULL; + edge_data->bottom_edges = NULL; /* Cleanup the timeouts */ if (edge_data->left_data.timeout_setup &&