Мой код страдает огромными утечками памяти, как показывает Вальгринд.Я читаю XML-файлы и не знаю, как правильно скопировать строковые значения в мою структуру без потери памяти.
Я пытался не дублировать строки, удаляя g_strdup
в on_button1_clicked
функция, но в случае, если она просто не работает (без вывода).
C файл:
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <glib-object.h>
#include <glib.h>
#include <glib/gprintf.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <string.h>
typedef struct {
gchar *name;
gint *age;
} item_struct;
typedef struct {
GtkWidget *main_win;
GtkWidget *button1;
item_struct item[10];
gint *item_index;
gchar *local_path;
} app_widgets;
void on_button1_clicked (GtkButton *button, app_widgets *app_wid)
{
g_printf("Button clicked !\n");
int i;
xmlDoc *doc;
xmlNodePtr root, node, unode;
gchar *filename = g_strdup_printf("%s/test.xml",app_wid->local_path);
doc = xmlReadFile((char*)filename, NULL, XML_PARSE_NOBLANKS);
root = xmlDocGetRootElement(doc);
if(root == NULL){
g_printf("%s: Document is empty!\n",filename);
return;
}
else {
node = root->children; //item
i=0;
while(node != NULL) {
unode = node->children;
xmlChar *xml_name = xmlNodeGetContent(unode);
app_wid->item[i].name = g_strdup((gchar*)xml_name);
xmlFree(xml_name);
unode = unode->next;
xmlChar *xml_age = xmlNodeGetContent(unode);
app_wid->item[i].age = GINT_TO_POINTER((gint)g_ascii_strtoll(g_strdup((gchar*)xml_age),NULL,10));
xmlFree(xml_age);
i++;
node = node->next;
}
app_wid->item_index = GINT_TO_POINTER((gint)i);
}
xmlFreeDoc(doc);
xmlCleanupParser();
g_free(filename);
for(i=0;i<GPOINTER_TO_INT(app_wid->item_index);i++) {
g_printf("%d name:%s age:%d\n",i,app_wid->item[i].name,GPOINTER_TO_INT(app_wid->item[i].age));
}
}
void on_main_win_destroy(GtkWidget *object)
{
gtk_main_quit();
}
int main(int argc, char *argv[])
{
GtkBuilder *builder;
app_widgets *widgets = g_slice_new(app_widgets);
gtk_init(&argc, &argv);
builder = gtk_builder_new();
gtk_builder_add_from_file (builder, "test52.glade", NULL);
widgets->main_win = GTK_WIDGET(gtk_builder_get_object(builder, "main_win"));
widgets->button1 = GTK_WIDGET(gtk_builder_get_object(builder, "button1"));
widgets->local_path = g_strdup("/home/bobby/tmptest52");
gtk_builder_connect_signals(builder, widgets);
gtk_widget_show(widgets->main_win);
g_object_unref(builder);
gtk_main();
g_slice_free(app_widgets, widgets);
return 0;
}
файл glade:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.12"/>
<object class="GtkWindow" id="main_win">
<property name="can_focus">False</property>
<signal name="destroy" handler="on_main_win_destroy" swapped="no"/>
<child>
<object class="GtkFixed" id="fixed1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkButton" id="button1">
<property name="label" translatable="yes">Test</property>
<property name="width_request">100</property>
<property name="height_request">80</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="on_button1_clicked" swapped="no"/>
</object>
<packing>
<property name="x">144</property>
<property name="y">81</property>
</packing>
</child>
</object>
</child>
</object>
</interface>
test.xmlfile:
<?xml version="1.0" encoding="UTF-8"?>
<document>
<item>
<name>Georges</name>
<age>19</age>
</item>
<item>
<name>Arthur</name>
<age>53</age>
</item>
<item>
<name>Louisa</name>
<age>22</age>
</item>
<item>
<name>Walter</name>
<age>42</age>
</item>
<item>
<name>Richard</name>
<age>28</age>
</item>
</document>
Я ожидал, что удаление g_strdup
подойдет, но даже с приведением (gchar*)
значения не передаются.
Обновление - отчет из valgrind (есть2 раза одна и та же ошибка, но я копирую только одну):
==5956== 645 bytes in 215 blocks are definitely lost in loss record 6,472 of 6,728
==5956== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5956== by 0x5A0B7B8: g_malloc (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4800.2)
==5956== by 0x5A2458E: g_strdup (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.4800.2)
==5956== by 0x4010E4: on_button1_clicked (main.c:68)
==5956== by 0x57791D3: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4800.2)
==5956== by 0x57939A5: g_signal_emit_valist (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4800.2)
==5956== by 0x579408E: g_signal_emit (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4800.2)
==5956== by 0x4F5A6AC: ??? (in /usr/lib/x86_64-linux-gnu/libgtk-3.so.0.1800.9)
==5956== by 0x4F5A714: ??? (in /usr/lib/x86_64-linux-gnu/libgtk-3.so.0.1800.9)
==5956== by 0x57791D3: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4800.2)
==5956== by 0x57939A5: g_signal_emit_valist (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4800.2)
==5956== by 0x579408E: g_signal_emit (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.4800.2)