iiukyr4uk
iiukyr4uk

Reputation: 35

gtk handler has bad data

I have some buttons and I want to trace what button was pressed. After button was pressed I need to show a new window or dialog with different data in dependence of button that was pressed

for(j = 0; j < 4; j++)
{
    eventbox = gtk_event_box_new();
    show_button[j] = gtk_button_new_with_label (label);
    gtk_table_attach_defaults (GTK_TABLE (table), eventbox, left_pos, right_pos , top_pos, bot_pos);
    gtk_container_add(GTK_CONTAINER(eventbox), show_button[j]);
    g_signal_connect (G_OBJECT (show_button[j]), "clicked", G_CALLBACK (show), &j);

    left_pos = right_pos + shift;
    right_pos = left_pos + width;
    gtk_widget_modify_bg(eventbox, GTK_STATE_NORMAL, &color[0]);                
}

And my handler is

void show(GtkWidget *window, gpointer data)
{
    int i = *(int*)data;
    printf("%d\n", i);
    GtkWidget *marking_table;
    window[i]  = gtk_window_new (GTK_WINDOW_POPUP);
    gtk_widget_set_size_request(window[i], 1000, 700);
    gtk_window_set_policy (GTK_WINDOW (window[i]), FALSE, FALSE, TRUE); 
    gtk_window_set_position(GTK_WINDOW(window[i]), 1);
    gtk_widget_set_app_paintable(window[i], TRUE);
    g_signal_connect (G_OBJECT (window[i]), "delete_event", G_CALLBACK (delete_event), NULL);
    marking_table = gtk_table_new (1000, 700, TRUE);
    gtk_container_add (GTK_CONTAINER (window[i]), marking_table);
}

I often have segfault because of "i" = 20350345 for example. May be there is another way to understand what button was pressd?

Any help is welcomed!

Upvotes: 1

Views: 59

Answers (1)

Jussi Kukkonen
Jussi Kukkonen

Reputation: 14577

Your userdata is a pointer to 'j'. When 'j' goes out of scope, the pointer keeps pointing to memory that may then be used for something else.

You'll have to either allocate memory for the userdata (typically a struct with all the data you need) or in this particular case where you only need the one int you can also use GLib Type Conversion Macros:

g_signal_connect (G_OBJECT (show_button[j]), "clicked",
                  G_CALLBACK (show), GINT_TO_POINTER(j));

Then in the handler use int i = GPOINTER_TO_INT(data).

Upvotes: 2

Related Questions