I have provided my sample code below. I am getting a memory leak. If I do all in main, i can mange memory-leak, but I want to do the way I have written the code and resolve the leak. Any suggestions?
I am using gtk 3.22.30.
This is my code:
#include <stdio.h>
#include <gtk/gtk.h>
#include <cairo-pdf.h>
#include <fontconfig/fontconfig.h>
#define NUM_NAMES 4
const gchar* names [] = {"Andrew", "Joe", "Samantha", "Jonathan"};
static void destroy (GtkWidget*, gpointer);
static gboolean delete_event (GtkWidget*, GdkEvent*, gpointer);
gboolean draw_text (GtkWidget* w, cairo_t* cr, gchar* data);
static gboolean draw_callback (GtkWidget *widget, cairo_t *cr, gpointer data);
static GtkWidget* main_rowcol = (GtkWidget*) NULL;
static GtkWidget* drawing_area = (GtkWidget*) NULL;
static GtkWidget* window = (GtkWidget*) NULL;
GdkDisplay *display;
GdkScreen* screen;
static cairo_scaled_font_t * scaled_font;
static cairo_font_face_t * font_face;
int num_glyphs;
int num_clusters;
static cairo_text_cluster_flags_t cluster_flags;
static cairo_glyph_t * glyph = NULL;
static cairo_text_cluster_t *clusters = NULL;
static cairo_surface_t * surface ;
gboolean draw_text (GtkWidget* w, cairo_t* cr, gchar* data) {
if (cr ==NULL) {
fprintf (stderr, "cairo is NULL\n");
return FALSE;
}
guint width, height;
int tick1;
int tick2;
int i;
char buf[32];
int text_width =0;
int text_half_width =0;
int font_off =0;
width = gtk_widget_get_allocated_width (w);
height = gtk_widget_get_allocated_height (w);
tick1 = width/2;
tick2 = height/2;
cairo_save (cr);
font_face = cairo_toy_font_face_create("courier", CAIRO_FONT_SLANT_NORMAL,CAIRO_FONT_WEIGHT_NORMAL);
surface = cairo_pdf_surface_create("test.pdf", 300, 300);
cairo_set_font_face(cr, font_face);
cairo_set_font_size(cr, 30);
scaled_font = cairo_get_scaled_font(cr);
cairo_text_extents_t extents_text;
cairo_font_extents_t extents_font;
GdkRGBA white;
gdk_rgba_parse (&white, "black");
gdk_cairo_set_source_rgba (cr, &white);
cairo_set_font_size(cr, 18);
cairo_font_extents (cr, &extents_font);
cairo_text_extents (cr,data, &extents_text);
text_width = (int)extents_text.width;
text_half_width = (int)(text_width/2 +0.5);
font_off = (int)extents_font.descent;
cairo_move_to (cr,tick1-text_half_width, tick2+font_off);
cairo_show_text (cr, data);
return TRUE;
}
static gboolean draw_callback (GtkWidget *widget, cairo_t *cr, gpointer data) {
guint width, height;
width = gtk_widget_get_allocated_width (widget);
height = gtk_widget_get_allocated_height (widget);
GtkStyleContext *context;
context = gtk_widget_get_style_context (widget);
gtk_render_background (context, cr, 0, 0, width, height);
gchar* text = "Heading";
draw_text (widget, cr, text);
return TRUE;
}
int main(int argc, char*argv []){
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_container_set_border_width (GTK_CONTAINER(window),10);
//gtk_widget_set_name (window, "gtkWin");
gtk_widget_set_size_request (window, 600,600);
main_rowcol = gtk_grid_new ();
gtk_grid_set_row_spacing (GTK_GRID (main_rowcol), 0);
gtk_grid_set_column_spacing (GTK_GRID (main_rowcol),0);
gtk_grid_set_row_homogeneous (GTK_GRID (main_rowcol), FALSE);
gtk_grid_set_column_homogeneous(GTK_GRID(main_rowcol),FALSE);
gtk_container_add (GTK_CONTAINER (window), main_rowcol);
drawing_area = gtk_drawing_area_new ();
gtk_widget_set_size_request (drawing_area, 300, 300);
g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (destroy), NULL);
g_signal_connect (G_OBJECT (window), "delete_event", G_CALLBACK (delete_event), NULL);
unsigned int refcount = cairo_font_face_get_reference_count (font_face);
g_signal_connect (G_OBJECT (drawing_area), "draw", G_CALLBACK (draw_callback),NULL);
refcount = cairo_font_face_get_reference_count (font_face);
gtk_grid_attach (GTK_GRID(main_rowcol),drawing_area,0,0,10,10);
gtk_widget_show_all (window);
cairo_glyph_free(glyph);
cairo_text_cluster_free (clusters);
cairo_surface_destroy(surface);
cairo_debug_reset_static_data();
FcFini();
gtk_main();
return 0;
}
static void destroy (GtkWidget *window, gpointer data ) {
gtk_main_quit ();
}
static gboolean delete_event (GtkWidget* window, GdkEvent *event, gpointer data ) {
return FALSE;
}
memory_leak:
IT has been maintained in several sources. But I think, the leak has something to do with the coding part.
360 (256 direct, 104 indirect) bytes in 1 blocks are definitely lost in loss record 5,072 of 5,418
==14200== at 0x4C29F73: malloc (vg_replace_malloc.c:309)
==14200== by 0x7131109: ??? (in /usr/lib64/libfontconfig.so.1.11.1)
==14200== by 0x7131844: ??? (in /usr/lib64/libfontconfig.so.1.11.1)
==14200== by 0x7132404: FcPatternDuplicate (in /usr/lib64/libfontconfig.so.1.11.1)
==14200== by 0x694360E: ??? (in /usr/lib64/libcairo.so.2.11512.0)
==14200== by 0x694395A: ??? (in /usr/lib64/libcairo.so.2.11512.0)
==14200== by 0x68F5D6F: cairo_toy_font_face_create (in /usr/lib64/libcairo.so.2.11512.0)
==14200== by 0x401ABA: draw_text(_GtkWidget*, _cairo*, char*) (test74.cpp:48)
==14200== by 0x401D4D: draw_callback(_GtkWidget*, _cairo*, void*) (test74.cpp:79)
==14200== by 0x5068240: ??? (in /usr/lib64/libgtk-3.so.0.2200.30)
==14200== by 0x51B0C91: ??? (in /usr/lib64/libgtk-3.so.0.2200.30)
==14200== by 0x6BBAC46: ??? (in /usr/lib64/libgobject-2.0.so.0.5600.1)