在C中初始化GtkWidget *的表

时间:2015-11-21 14:46:53

标签: c pointers gtk side-effects

我正在用GTK2编写一个简单的C应用程序。

我有一点问题 - 我必须创建一个9x9条目小部件表,所以我认为创建一个GtkWidget数组并在循环中使用它是个好主意。< / p>

但是......当我将这个数组的元素传递给GTK函数时,我的程序崩溃了。

我声明这个数组:

GtkWidget* entries[9][9];

之后,我有一个功能:

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);
        }
    }
}

最后在addField我使用这样的条目:

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

之后,当我尝试访问上面代码中初始化的元素时,程序崩溃,例如:

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
        }
    }
}

1 个答案:

答案 0 :(得分:0)

除非我错了,否则您似乎无法在任何地方初始化entires。 结果,在

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

认为你传递了一堆完全随机的指针,导致了segfaulting。

首先尝试初始化entries,例如:

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);
    }
}

编辑:您在评论中提到您在addField初始化它。

我没有注意到它,实际上我没有费心去寻找addField 内的初始化(原因很快就会明白)。

我的坏。

让我们看看发生了什么。

您正在addField范围内创建对象,并将其指定给指针GtkWidget* field

很好,但指针 GtkWidget* field是通过值还是通过引用传递的?

根据价值,您在void addField内所做的事情对entries[i][j]的值无影响

如果您对(预先存在的)对象执行操作,而不更改指针的值,是的 - 这几乎是指针的好处 - 但是如果您要更改指针本身的值,没有。

所以you need to pass a pointer to pointer,是

的影响
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
                     );

}

当然

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

然而,这可能会非常难看,因此您可能只想在外面 进行初始化。