Search code examples
carrayspointersgtkgtk3

GTK+/C: Passing data through g_signal_connect changes the data


I've looked at GTK+ g_pointer_connect passing data incorrectly but even after trying to do what people told there, my problem still persisted.

What I need to do is pass an array from an array of arrays.

The code that declares this array is here

    int **BtnLoc = malloc(sizeof(int*) * 9);
    for (int i = 0; i < 9; i++) {
        BtnLoc[i] = malloc(sizeof(*BtnLoc[i]) * 3);
     }

The code that uses this is this

unsigned int counter = 0;
for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
        int x[2] = {i, j};
        BtnLoc[counter] = x;
        buttons[i][j] = gtk_button_new();
        gtk_table_attach_defaults(
                            GTK_TABLE(table),
                            buttons[i][j],
                            i, i+1, j, j+1
                        );
        g_signal_connect(
                        buttons[i][j],
                        "clicked",
                        G_CALLBACK(Toggled),
                        BtnLoc[counter]
                    );
        counter++;
    }
}

In the Toggled() function it prints x[0] and x[1], but instead of them being 0 and 1 or 2 and 1, they're complete garbage like -1924531234 and 24539


Solution

  • Your code doesn't make sense. You first declare an array of 9 pointers to arrays of 3 ints, but then you fill it in a completely different way. You're assigning ints where you told the compiler that you would store pointer to integers.

    So I suppose what you want instead of

    BtnLoc[counter] = x;
    

    is:

    *BtnLoc[counter] = x;
    

    This still has issues: you created an array of arrays containing each 3 ints, but only initialize 2, so the content of the third memory location is undefined.

    Just use the dynamic array types provided in the GLib (like GArray or GptrArray) and avoid those issues, as this usualy makes the code easier to read.

    EDIT:

    It seems that's a XY problem. You seem to want to store the buttons location in an array, but I don't see why you want to do that in the first place.