[xlib] Fix memory leaks in xlib backend
Hello.
There are memory leaks in the cairo xlib backend.
cc `pkg-config --cflags cairo x11` `pkg-config --libs cairo x11` cairo-xlib.c -o cairo-xlib
cairo-xlib.c
#include <X11/Xlib.h>
#include <cairo.h>
#include <cairo-xlib.h>
#include <math.h>
#include <stdio.h>
/* from https://www.cairographics.org/samples/arc/ */
void draw (cairo_t *cr)
{
double xc = 128.0;
double yc = 128.0;
double radius = 100.0;
double angle1 = 45.0 * (M_PI/180.0); /* angles are specified */
double angle2 = 180.0 * (M_PI/180.0); /* in radians */
cairo_set_line_width (cr, 10.0);
cairo_arc (cr, xc, yc, radius, angle1, angle2);
cairo_stroke (cr);
/* draw helping lines */
cairo_set_source_rgba (cr, 1, 0.2, 0.2, 0.6);
cairo_set_line_width (cr, 6.0);
cairo_arc (cr, xc, yc, 10.0, 0, 2*M_PI);
cairo_fill (cr);
cairo_arc (cr, xc, yc, radius, angle1, angle1);
cairo_line_to (cr, xc, yc);
cairo_arc (cr, xc, yc, radius, angle2, angle2);
cairo_line_to (cr, xc, yc);
cairo_stroke (cr);
}
int main ()
{
cairo_surface_t *surface;
cairo_t *cr;
Display *display;
Window window;
int screen;
int width = 250;
int height = 250;
Atom delete_window;
display = XOpenDisplay (NULL);
if (!display)
{
puts ("Can't open display");
return 1;
}
screen = DefaultScreen (display);
window = XCreateSimpleWindow (display, XDefaultRootWindow (display),
0, 0, width, height,
1, BlackPixel (display, 0), WhitePixel (display, 0));
delete_window = XInternAtom (display, "WM_DELETE_WINDOW", False);
XSetWMProtocols (display, window, &delete_window, 1);
XSelectInput (display, window, ExposureMask);
XMapWindow (display, window);
surface = cairo_xlib_surface_create (display, window,
DefaultVisual (display, screen), width, height);
cr = cairo_create (surface);
while (1)
{
XEvent event;
XNextEvent (display, &event);
if (event.type == Expose)
{
draw (cr);
}
else if (event.type == ClientMessage &&
event.xclient.data.l[0] == delete_window)
break;
}
cairo_destroy (cr);
cairo_surface_destroy (surface);
XDestroyWindow (display, window);
XCloseDisplay (display);
return 0;
}
% valgrind --leak-check=full ./cairo-xlib
==86579== Memcheck, a memory error detector
==86579== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==86579== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==86579== Command: ./cairo-xlib
==86579==
==86579==
==86579== HEAP SUMMARY:
==86579== in use at exit: 16,040 bytes in 14 blocks
==86579== total heap usage: 239 allocs, 225 frees, 125,320 bytes allocated
==86579==
==86579== 360 bytes in 1 blocks are definitely lost in loss record 5 of 14
==86579== at 0x484C8A4: malloc (in /usr/local/libexec/valgrind/vgpreload_memcheck-amd64-freebsd.so)
==86579== by 0x4941A46: source (in /usr/local/lib/libcairo.so.2.11704.0)
==86579== by 0x49419C4: color_source (in /usr/local/lib/libcairo.so.2.11704.0)
==86579== by 0x493FFFC: _cairo_xlib_source_create_for_pattern (in /usr/local/lib/libcairo.so.2.11704.0)
==86579== by 0x491BA62: clip_and_composite (in /usr/local/lib/libcairo.so.2.11704.0)
==86579== by 0x491A958: _cairo_traps_compositor_stroke (in /usr/local/lib/libcairo.so.2.11704.0)
==86579== by 0x48BCBA6: _cairo_compositor_stroke (in /usr/local/lib/libcairo.so.2.11704.0)
==86579== by 0x49449BA: _cairo_xlib_surface_stroke (in /usr/local/lib/libcairo.so.2.11704.0)
==86579== by 0x4914363: _cairo_surface_stroke (in /usr/local/lib/libcairo.so.2.11704.0)
==86579== by 0x48C4F60: _cairo_gstate_stroke (in /usr/local/lib/libcairo.so.2.11704.0)
==86579== by 0x48BFBBC: _cairo_default_context_stroke (in /usr/local/lib/libcairo.so.2.11704.0)
==86579== by 0x4923059: cairo_stroke (in /usr/local/lib/libcairo.so.2.11704.0)
==86579==
==86579== 360 bytes in 1 blocks are definitely lost in loss record 6 of 14
==86579== at 0x484C8A4: malloc (in /usr/local/libexec/valgrind/vgpreload_memcheck-amd64-freebsd.so)
==86579== by 0x4941A46: source (in /usr/local/lib/libcairo.so.2.11704.0)
==86579== by 0x49419C4: color_source (in /usr/local/lib/libcairo.so.2.11704.0)
==86579== by 0x4940294: _cairo_xlib_source_create_for_pattern (in /usr/local/lib/libcairo.so.2.11704.0)
==86579== by 0x491BA62: clip_and_composite (in /usr/local/lib/libcairo.so.2.11704.0)
==86579== by 0x491B77B: clip_and_composite_polygon (in /usr/local/lib/libcairo.so.2.11704.0)
==86579== by 0x491A601: _cairo_traps_compositor_fill (in /usr/local/lib/libcairo.so.2.11704.0)
==86579== by 0x48BCCA6: _cairo_compositor_fill (in /usr/local/lib/libcairo.so.2.11704.0)
==86579== by 0x4944AF2: _cairo_xlib_surface_fill (in /usr/local/lib/libcairo.so.2.11704.0)
==86579== by 0x4914164: _cairo_surface_fill (in /usr/local/lib/libcairo.so.2.11704.0)
==86579== by 0x48C53EF: _cairo_gstate_fill (in /usr/local/lib/libcairo.so.2.11704.0)
==86579== by 0x48BFC6C: _cairo_default_context_fill (in /usr/local/lib/libcairo.so.2.11704.0)
==86579==
==86579== LEAK SUMMARY:
==86579== definitely lost: 720 bytes in 2 blocks
==86579== indirectly lost: 0 bytes in 0 blocks
==86579== possibly lost: 0 bytes in 0 blocks
==86579== still reachable: 15,320 bytes in 12 blocks
==86579== suppressed: 0 bytes in 0 blocks
==86579== Reachable blocks (those to which a pointer was found) are not shown.
==86579== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==86579==
==86579== For lists of detected and suppressed errors, rerun with: -s
==86579== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
This patch fixes these memory leaks.