Memory Leak with pango_layout_new()
- From: martin dempsey <mdempsey kgisystems com>
- To: gtk-app-devel-list gnome org
- Cc: esepich kgisystems com, jgeorge kgisystems com
- Subject: Memory Leak with pango_layout_new()
- Date: Thu, 9 Sep 2004 12:31:53 -0700
I've got a major memory leak in an applicaton and I tracked it down to the
following: if I create a PangoLayout with pango_layout_new() and then use
pango_layout_set_text(), I get a memory leak even when I try to free the
memory with g_object_unref(). However, if I replace those function calls with
a call to gtk_widget_create_pango_layout(), there is no memory leak. The
memory leak is very obvious: on the real app, I'm losing almost 3 Megabytes
per hour. "memprof" also very clearly shows the leak. I'm using Debian
"sarge" and with the standard versions of the gtk development packages for
that OS. I am pretty new with gtk programming. Am I doing something simple
wrong?
PangoLayout *layout;
#ifdef LEAK /* leaks memory */
layout = pango_layout_new(gdk_pango_context_get());
pango_layout_set_text(layout, some_text, -1);
#else /* doesn't leak memory */
layout = gtk_widget_create_pango_layout(GTK_WIDGET(window),some_text);
#endif
g_object_unref(layout);
I've attached a small (less than 120 line) example program. I compiled the
program with :
gcc -g -o example example.c `pkg-config --libs gtk+-2.0` \
`pkg-config --cflags gtk+-2.0`
if you comment out the "#define LEAKS" it won't leak memory. otherwise it
will. Any help will be appreciated.
----------------------Example program below ------------------------------
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#define XSIZE 200
#define YSIZE 100
#define LEAKS
GtkWidget *window;
int depth;
gboolean redrawtimer(gpointer data);
void suspectDrawText(GdkDrawable *pixmap, GdkGC *gc, char *m_text)
{
PangoLayout *layout;
PangoFontDescription *fontdesc;
PangoRectangle ink, logical;
#ifdef LEAKS
layout = pango_layout_new(gdk_pango_context_get());
pango_layout_set_text(layout, m_text, -1);
#else
layout = gtk_widget_create_pango_layout(GTK_WIDGET(window),m_text);
#endif
fontdesc = pango_font_description_from_string ("Helvetica Bold 14");
pango_layout_set_font_description (layout, fontdesc);
pango_layout_get_extents(layout,&ink,&logical);
int howwide = 10, howhigh = ink.height/2/1024 - ink.y/1024;
gdk_draw_layout(pixmap,gc ,howwide ,howhigh , layout);
pango_font_description_free(fontdesc);
g_object_unref(layout);
}
GtkWidget *setWidget(GtkWidget *widgetIn, char *sometext)
{
GdkPixmap* pmap = gdk_pixmap_new(window->window,XSIZE,YSIZE,depth);
GdkGC* gc = gdk_gc_new(pmap);
GdkScreen *pscreen = gdk_screen_get_default();
GdkColormap* cm = gdk_screen_get_default_colormap(pscreen);
GdkColor fgcolor;
if ( gdk_color_parse ("black", &fgcolor)) {
if ( gdk_colormap_alloc_color(cm, &fgcolor,TRUE,TRUE)) {
gdk_gc_set_foreground(gc,&fgcolor);
gdk_draw_rectangle(pmap,gc,TRUE,00,00,XSIZE,YSIZE); // flood it
}
}
GdkColor bgcolor;
if ( gdk_color_parse ("white", &bgcolor)) {
if ( gdk_colormap_alloc_color(cm, &bgcolor,TRUE,TRUE)) {
gdk_gc_set_foreground(gc,&bgcolor);
suspectDrawText(pmap,gc,sometext);
}
}
g_object_unref (gc);
if (widgetIn != NULL) {
gtk_image_set_from_pixmap ( GTK_IMAGE(widgetIn),pmap,NULL);
}
else {
widgetIn = gtk_image_new_from_pixmap (pmap,NULL);
}
g_object_unref (pmap);
return widgetIn;
}
gboolean redrawtimer(gpointer data)
{
GtkWidget *theWidget = (GtkWidget *) data;
time_t now;
time(&now);
char *thetime = ctime(&now);
thetime[19] = 0;
setWidget(theWidget, thetime +11) ;
return TRUE;
}
static gboolean delete_event( GtkWidget *widget, GdkEvent *event, gpointer
data )
{
return FALSE;
}
static void destroy( GtkWidget *widget, gpointer data )
{
gtk_main_quit ();
}
int main( int argc, char *argv[] )
{
GtkWidget *image;
GtkWidget *fixed;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL); /* create a new window */
fixed = gtk_fixed_new();
gtk_container_add (GTK_CONTAINER (window), fixed);
g_signal_connect (G_OBJECT (window), "delete_event",
G_CALLBACK (delete_event), NULL);
g_signal_connect (G_OBJECT (window), "destroy",
G_CALLBACK (destroy), NULL);
gtk_widget_set_size_request (window,XSIZE,YSIZE);
gtk_widget_show(window);
depth = gdk_drawable_get_depth(window->window);
g_print("Depth = %d\n",depth);
image = setWidget(NULL,"Startup");
gtk_fixed_put(GTK_FIXED(fixed),image,0,0);
gtk_widget_show_all (window);
g_timeout_add(100,redrawtimer,image);
gtk_main (); // the app sits here in the main loop
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]