在 C 中初始化 GtkWidget* 的 table

Initializing a table of GtkWidget* in C

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

我有一个小问题 - 我必须创建一个 9x9 table 条目小部件,所以我认为创建一个 GtkWidget 数组并使用它在循环等

但是...当我将此数组的一个元素传递给 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
        }
    }
}

除非我错了,你似乎没有在任何地方初始化entires。 结果,在

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

认为你正在传递一堆导致段错误的完全随机的指针。

先尝试初始化 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);

然而,这可能会变得非常丑陋,因此您可能希望在 外部.

简单地初始化它