GList问题(GTK +,C)

时间:2014-05-16 18:08:10

标签: c list gtk glib

我在将字符串保存为闪电时遇到了很多麻烦。当我添加一个新字符串时,当我使用" FOR"打印整个列表时,所有前面的元素都会消失。它只是出现在我添加的最后一个,在列表中的其他空格中只是垃圾,就像这样:

OUTPUT按下按钮15

guardo el elemento:"15"
numero: "15"

OUTPUT按下按钮11

guardo el elemento:"11"
numero: ""
numero: "11"

OUTPUT按下按钮10

guardo el elemento:"10" 
numero: ""
numero: ""
numero: "10"

OUTPUT按下按钮6

guardo el elemento:"6"
numero: ""
numero: ""
numero: "0�"
numero: "6"

我的列表在下一个结构中声明

typedef struct widgets {
  ...
  GList *LISTA;

}WIDGETS;

并在主

中初始化
gint main(gint argc,gchar *argv[])
{
 ...
  WIDGETS *boton;
  // 1.- Inicializar el ambiente
  gtk_init(&argc, &argv);
  boton = malloc(sizeof(WIDGETS));
  boton->tipojuego=1;
  boton->numMov=0;
  boton->bandera=2;
  g_timeout_add(1000,tiempo,boton);
  boton->LISTA=NULL;

...
}

保存和打印列表元素的功能是(" elementos"指向与boton相同):

void movimientos(GtkWidget *widget,gpointer info)
{
  WIDGETS *elementos=(WIDGETS*)info;

  gchar *str;
  gpointer infor;
  gint i;

  //str=malloc(3*sizeof(char));
  str=gtk_widget_get_name(widget);
  g_print("guardo el elemento:\"%s\" \n",str);

  elementos->LISTA=g_list_append(elementos->LISTA, str); 
  // g_print("Ya se guardo %s",(gchar *)g_list_last(elementos->LISTA)->data);

  for(i=0;i<g_list_length(elementos->LISTA);i++)
    {
      infor=g_list_nth_data(elementos->LISTA,i);

    str=(gchar *)infor;
    g_print("\nnumero: \"%s\"",str);
    }
}

1 个答案:

答案 0 :(得分:1)

您不应该将malloc与GLIB一起使用:使用g_new()g_new0()。您还应首先初始化boton结构,特别是考虑到您将其传递给其他功能;不要使用赋值和函数调用交错初始化。

主要问题是gtk_widget_get_name()返回一个const字符串,因此如果窗口小部件消失,返回的字符串将包含垃圾。您需要连接到GtkWidget::destroy信号并从列表中删除元素,或者您必须复制gtk_widget_get_name()返回的字符串,然后再将其添加到列表中(然后记住释放列表的内容以及列表。

然后问题是你的循环列表是一个非常低效的循环GList的方法:

在每次迭代时询问列表的长度,这意味着每次迭代列表;然后你使用g_list_nth_data(),它会迭代列表,直到它到达索引。一个双向链表是不是一个数组,但你使用的是前者,因为它是后者。迭代列表的正确方法是:

GList *l = elementos->LISTA;
for (l = list; l != NULL; l = l->next) {
    const char *str = l->data;

    // ...
}

作为C编程质量和风格的附注:不要混合小写(botonelementos)和大写(WIDGETS,{{1 }})以这种方式(坚持一个案例),并且你重新投入很多(LISTAgpointer的typedef并由C隐式投射。

但是,在所有这些之后,我仍然无法理解问题是,因为你没有提供足够的背景来准确回复。看起来你并不精通C,这让我觉得你应该在尝试使用C API之前使用更高级别的语言使用GTK +。