Usando o main loop da GLib para liberar memória temporária
- Posted by acidx on January 2nd, 2007 filed in c, glib, gtk, hack, idle_free, programming
- Comment now »
(English version below.)
Quando se programa com GTK+ (ou GLib) em C, muitas vezes faz-se necessário o uso de variáveis temporárias alocadas dinamicamente. O problema é ter que lembrar de liberá-las na hora correta — ou pior — ter que usar mais variávies auxiliares, como no exemplo abaixo:
gchar *funcao(void) {
gchar *temp = g_strdup("sou uma string temporaria");
return g_strdup_printf("%s -> %f", temp, G_PI);
}
Nesse exemplo, a variável temp irá vazar memória, pois ela não foi liberada após a execução do g_strdup_printf e do retorno da função. Uma maneira de resolver isso seria reescrevendo funcao como:
gchar *funcao(void) {
gchar *temp = g_strdup("sou uma string temporaria");
gchar *temp2 = g_strdup_printf("%s -> %f", temp, G_PI);
g_free(temp);
return temp2;
}
Agora está melhor: a variável temp não irá vazar, mas fomos obrigados a usar mais uma variável. A solução que proponho é bem simples, mas requer que seu programa rode na main loop da GLib. É para ser usado apenas em funções de callback. Não é threadsafe. Inclua essas duas pequenas funções em seu programa:
static gboolean __idle_free_do(gpointer ptr) {
g_free(ptr);
return FALSE;
}
void gpointer idle_free(gpointer ptr) {
g_idle_add(__idle_free_do, ptr);
return ptr;
}
Agora podemos reescrever a função teste como:
gchar *funcao(void) {
gchar *temp = idle_free(g_strdup("sou uma string temporaria"));
return g_strdup_printf("%s -> %f", temp, G_PI);
}
Assim a variável temp será liberada logo que o loop da GLib estiver livre para processar eventos. É uma idéia simples e prática… acho que deveria ser inclusa na GLib por padrão.
(façam o uso que quiser desse código, está em domínio público)
Using GLib main loop to free up temporary memory
When you program with GTK+ (or GLib) with C, sometimes there’s a need for temporary dynamically-allocated variables. The problem is to free them in the right time — or worse — having to use even more auxiliary variables, like in the example below:
gchar *func(void) {
gchar *temp = g_strdup("i am a temporary string");
return g_strdup_printf("%s -> %f", temp, G_PI);
}
In this example, the temp variable will leak memory, since it was not freed after g_strdup_printf. A way to fix this would be rewriting func as:
gchar *func(void) {
gchar *temp = g_strdup("i am a temporary string");
gchar *temp2 = g_strdup_printf("%s -> %f", temp, G_PI);
g_free(temp);
return temp2;
}
Much better: temp won’t leak anymore, but we had to use another variable. I propose a simpler solution, but it requires that your program runs in the GLib main loop. It should be used only on callback functions and is not threadsafe. Include these two tiny functions in your program:
static gboolean __idle_free_do(gpointer ptr) {
g_free(ptr);
return FALSE;
}
void gpointer idle_free(gpointer ptr) {
g_idle_add(__idle_free_do, ptr);
return ptr;
}
Now we can rewrite func as:
gchar *func(void) {
gchar *temp = idle_free(g_strdup("i am a temporary variable"));
return g_strdup_printf("%s -> %f", temp, G_PI);
}
This way the memory will be freed as soon as GLib gains control and the main loop is ready to process events.












Leave a Comment