Greetings - I hope I am putting this in proper forum.
A program I am working on reports a memory leak when an invalid window is referenced. I have some example code which shows the problem. The two functions are identical except that the first is called with a valid window, while the second is called with an invalid window. You can see the different ways I've tried to free the memory, but Valgrind always complains. BTW, the bolded line of code is the one Valgrind complains about. Is there a way to fix this?
Code:
#include <stdlib.h>
#include <stdio.h>
#include <Xutil.h>
#include <Xlib.h>
Display *display = 0;
int _invalid_window_handler(Display *dsp, XErrorEvent *err) {
return 0;
}
void example1(Window win) {
XSetErrorHandler(_invalid_window_handler);
XWindowAttributes *attribs = calloc(1, sizeof(XWindowAttributes));
if(attribs == NULL) {
fprintf(stderr, "Unable to allocate space for XWindowAttributes");
return;
}
Status status = XGetWindowAttributes(display, win, attribs);
XSetErrorHandler(NULL);
printf("example1 status: %d\n", status);
XFree(attribs);
// free(attribs);
// if(status) {
// XFree(attribs);
// } else {
// free(attribs);
// }
}
void example2(Window win) {
XSetErrorHandler(_invalid_window_handler);
XWindowAttributes *attribs = calloc(1, sizeof(XWindowAttributes));
if(attribs == NULL) {
fprintf(stderr, "Unable to allocate space for XWindowAttributes");
return;
}
Status status = XGetWindowAttributes(display, win, attribs);
XSetErrorHandler(NULL);
printf("example2 status: %d\n", status);
XFree(attribs);
// free(attribs);
// if(status) {
// XFree(attribs);
// } else {
// free(attribs);
// }
}
int main(int argc, char* argv[]) {
Window real = 0;
int state_ignored = 0;
display = XOpenDisplay(NULL);
int success = XGetInputFocus(display, &real, &state_ignored);
if(!success) {
return -1;
}
Window fake = (Window)2L;
example1(real);
example2(fake);
XCloseDisplay(display);
display = 0;
return 0;
}
What Valgrind has to say
==14330== Memcheck, a memory error detector.
==14330== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==14330== Using LibVEX rev 1804, a library for dynamic binary translation.
==14330== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==14330== Using valgrind-3.3.0-Debian, a dynamic binary instrumentation framework.
==14330== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==14330== For more details, rerun with: -v ==14330==
example1 status: 1
example2 status: 0
==14330==
==14330== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 23 from 1) ==14330== malloc/free: in use at exit: 62 bytes in 2 blocks.
==14330== malloc/free: 90 allocs, 88 frees, 58,630 bytes allocated.
==14330== For counts of detected errors, rerun with: -v ==14330== searching for pointers to 2 not-freed blocks.
==14330== checked 105,428 bytes.
==14330==
==14330== 36 bytes in 1 blocks are definitely lost in loss record 2 of 2
==14330== at 0x4022AB8: malloc (vg_replace_malloc.c:207)
==14330== by 0x427C30D: (within /usr/lib/libxcb.so.1.0.0)
==14330== by 0x427AFB5: (within /usr/lib/libxcb.so.1.0.0)
==14330== by 0x427CBDC: xcb_wait_for_reply (in /usr/lib/libxcb.so.1.0.0)
==14330== by 0x407A1EA: _XReply (in /usr/lib/libX11.so.6.2.0)
==14330== by 0x40592FB: _XGetWindowAttributes (in /usr/lib/libX11.so.6.2.0)
==14330== by 0x4059451: XGetWindowAttributes (in /usr/lib/libX11.so.6.2.0)
==14330== by 0x80487A0:
example2 (test.c:39)
==14330== by 0x804884A: main (test.c:62)
==14330==
==14330== LEAK SUMMARY:
==14330== definitely lost: 36 bytes in 1 blocks.
==14330== possibly lost: 0 bytes in 0 blocks.
==14330== still reachable: 26 bytes in 1 blocks.
==14330== suppressed: 0 bytes in 0 blocks.
==14330== Reachable blocks (those to which a pointer was found) are not shown.