1

I'm writing a simple C app with GTK2.

I have a little problem - I must create a 9x9 table of entry widgets, so I think it is a good idea to create an array of GtkWidgets and use it in loops etc.

But... my program crashes when I pass an element of this array to a GTK function.

I declare the array like this:

GtkWidget* entries[9][9];

later, I have a function:

void drawBoard(GtkWidget* table, GtkWidget* entries[][9])
{
    for(last_i=1; last_i<10; last_i++)
    {
        for(last_j=1; last_j<10; last_j++)
        {
            addField(entries[last_i-1][last_j-1],table);
        }
    }
}

And finally in addField I use the entry like this:

void addField(GtkWidget* field, GtkWidget *table)
{
    field = gtk_entry_new_with_max_length(1);
    //rest of code
}

Afterwards, when I try to access the elements I initialized in the code above, the program crashes, for example:

void function(GtkWidget *entries[][9])
{
    int i,j=0;
    for(i=0; i<9; i++)
    {
        for(j=0; j<9; j++)
        {
            gtk_entry_set_width_chars(entries[i][j], 2);//<-- here app crashes
        }
    }
}
Tobia Tesan
  • 1,938
  • 17
  • 29
blidea
  • 25
  • 7

1 Answers1

0

Unless I'm wrong, you do not seem to be initializing entires anywhere. As a result, in

addField(entries[i][j],table,i,j);

I think you are passing a bunch of completely random pointers that result in segfaulting.

Try initializing entries first, e.g.:

for(i=0; i<9; i++)
{
    for(j=0; j<9; j++)
    {
        entries[i][j] = gtk_label_new ("button");
        addField(entries[i][j],table,i,j);
        fprintf(stderr,"%d %d",i,j);
    }
}

EDIT: You mention in your comment that you initialize it in addField.

I had not noticed it, in fact I hadn't bothered to look for initialization inside addField (for reasons that will be soon apparent).

My bad.

Let's see what's going on.

You are creating your object inside the scope of addField and assigning it to the pointer GtkWidget* field.

Nice, but is the pointer GtkWidget* field passed by value or by reference?

By value, so what you do inside void addField has no effect on the value of entries[i][j].

If you carried out operations on a (pre-existing) object, without changing the value of the pointer, yes - that's pretty much what pointers are good for -, but if you are changing the value of the pointer itself, no.

So you need to pass a pointer to pointer, something to the effect of

void addField(GtkWidget** field, GtkWidget *table, int i, int j)
{
    *field = gtk_entry_new_with_max_length(1);
    gtk_table_attach_defaults (GTK_TABLE (table), *field, j, j+1, i, i+1);
    gtk_widget_show (*field);
    gtk_entry_set_width_chars((GtkEntry*)*field, 2);
    gtk_widget_modify_font(*field, pango_font_description_from_string("Tahoma 25.4"));
    g_object_set_data(G_OBJECT(*field), "i", last_i);
    g_object_set_data(G_OBJECT(*field), "j", last_j);
    g_signal_connect (*field, "insert-text",
                      G_CALLBACK (edited_callback),
                      *field
                     );

}

and of course

        addField(&entries[i][j],table,i,j);

This can get pretty ugly, however, so you may want to simply initialized it outside.

Community
  • 1
  • 1
Tobia Tesan
  • 1,938
  • 17
  • 29
  • 1
    I initialize entries in function addField - in first line `field = gtk_entry_new_with_max_length(1);` field is pointer to entries[i][j], or not? – blidea Nov 22 '15 at 11:07
  • @blidea: glad I could help. Pointers in C can sometimes be tricky. Make sure you completely understand the basics before moving on to GTK development. And even then consider PyGTK :P If this has helped you consider also upvoting and accepting it as an answer. Good luck :) – Tobia Tesan Nov 22 '15 at 13:28
  • @blidea: I just realized that there is something very wrong with your idea that "`field` is pointer to `entries[i][j]`". In fact *they are both pointers to some object in the heap*. – Tobia Tesan Nov 25 '15 at 14:27