2015-11-21 2 views
1

Я пишу простое приложение C с GTK2.Инициализация таблицы GtkWidget * в C

У меня есть небольшая проблема - я должен создать 9x9 таблицу виджетов ввода, так что я думаю, что это хорошая идея, чтобы создать массив 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 
} 

Впоследствии, когда я пытаюсь получить доступ к элементам, которые я инициализировал в коде выше, программа cras ГЭС, например:

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

Какова ценность 'i',' j', когда он падает? –

+0

i и j - 0 – blidea

+0

mh. Пожалуйста, опубликуйте MWE, с которым мы можем работать в 'gdb', вам интересно. –

ответ

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

EDIT: Вы упоминаете в своем комментарии, что вы инициализировать его в addField.

Я не заметил этого, фактически Я не потрудился искать инициализацию внутри addField (по причинам, которые скоро будут очевидны).

Мой плохой.

Давайте посмотрим, что происходит.

Вы создаете свой объект в пределах addField и присваиваете его указателю GtkWidget* field.

Ницца, но есть указатель GtkWidget* field передано по значению или по ссылке?

По значению, так что вы делаете внутри void addField имеет не действует на значение entries[i][j].

Если вы проводили операции на (ранее существовавших) объектов, не изменяя значение указателя, да - это довольно много, что указатели хороши для -, но если вы изменяете значение указателя сам, no.

Так 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); 

Это может быть довольно некрасиво, однако, так что вы можете просто инициализировать его вне.

+1

Я инициализирую записи в функции addField - в первой строке 'field = gtk_entry_new_with_max_length (1);' поле является указателем на записи [i] [j] или нет? – blidea

+0

@blidea: ну, нет. См. Править. –

+1

Ницца! Оно работает! Большое спасибо :) – blidea

Смежные вопросы