I have a memory leak in C. Need help interpreting valgrind's output.
I've written a small GTK program and it definitely has a memory leak that I can see with top or ps. However, I can't make heads or tails of the valgrind output. I've looked at some simple tutorials and I don't get any of the messages that they get (e.g. "Conditional jump", "Invalid write", "Mismatched free ()", etc). I do, however, get the following leak summary:
Code:
==7987== LEAK SUMMARY: Code:
valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes --log-file=valgrind.log ./GTKalendar line 22 Code:
gtk_init (&argc, &argv); Code:
PangoFontDescription *prev_next = pango_font_description_from_string ("6"); Be aware that it will create a settings file named ~/.GTKalendar that you may want to delete afterwards. |
Look at the loss records, those show the backtrace of where in your code the allocation occurred that was not unallocated.
By the looks of things, a lot of stuff seems to have been allocated by various libraries, yet has not be unallocated. You should probably start by checking your program properly closes down. If you have 7 open file descriptors at shutdown, then you probably forgot to tell your libraries to un-init, and your widgets to destroy themselves, etc. |
First off, you shouldn't be using your header file, GTKalender.h, to store your functions. Header files are not meant to be libraries, they are meant to contain declarations (function declarations, constants, and so on) that one or more of the non-header C files will need to compile properly.
Valgrind is hard to interpret because of the way GTK works. Rather than driving the program yourself, you register a bunch of event handlers, and then GTK calls you as necessary. This is why Valgrind thinks that all of your memory is coming from gtk_init(). I think the other poster is correct, and the reports are merely because your program is not cleaning up when it shuts down. So, when you invoke gtk_event_box_new(), then any memory needed for this is "leaked", because when the program shuts down it is not freed. What I recommend is building a debug version of the program which cleans up memory on shutdown. This way you can use Valgrind to see if there are any "true" leaks. But in normal operation it is better simply to exit, since the OS will reclaim all memory used by the process. A good way to do this is by something like: Code:
#ifdef MEMORY_DEBUG Code:
#define NUM_BOXES (sizeof(day_box) / sizeof(day_box[0])) Good luck! |
I'm not particularly familiar with valgrind, but I do know that some developers consider a one-time allocation that's never deallocated a "non-leak." The reasoning is that the memory is implicitly released upon process exit, that there is still a pointer to it until that point (immediately disqualifying it as a leak,) and that it doesn't occur more than once. Some memory pool implementations use such rationale, so maybe GTK+ uses a similar pattern with gtk_init. I don't know, but it's something to think about.
ta0kira |
Hi all. Thanks for replying. I wanted you all to know I haven't abandoned this thread and I'm investigating some of the suggestions put forward.
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
adz |
Quote:
ta0kira |
Quote:
|
Hi all.
I've managed to substantially reduce the memory leak, essentially by calling gtk_widget_modify_* less often, and as a side effect made my app considerably more efficient. I still don't know why those function calls inflate memory usage. At least the problem is considerably smaller now. |
Remember that GTK+ creates pseudo-polymorphism through extensive use of macros. C doesn't have the built-in inheritance support that C++ does, so it all has to be done at a higher level of code. Some of those operations can be very complex to implement by hand and (as far as I know) it's done at the source level rather than at the binary level as with C++. I say "as far as I know" because the constructs have to be able to interface with macros in C.
ta0kira |
Hi again.
I've just recently written a super simple GTK app that just inverts the foreground and background colours every second as a test case. Now, as I watch the output of top, I see both VIRT and RES slowly creeping up. Have I got it completely wrong or is this a memory leak? Here is the code I used: Code:
#include <gtk/gtk.h> Thanks in advance. |
No leak observed here with your test code under Solaris Express.
|
Really? No difference in the number spat out by top or ps? Hmmm... Might be a problem specific to Linux and/or Debian. May I ask, how long did you run the program for and what version of the GTK libraries you have?
One more question. When free() is called under Solaris, is the memory free'd straightaway? I read somewhere that that was the case, or at least it was a possibility if one compiles with a special header file. As I understand it, under Linux, free'd memory just goes back into the malloc() pool and will only get truly free'd when the program exits. Edit: I've been running my app for almost 2 hours now and the RES column of top is up to 51m! |
Quote:
Then I modified your code to toggle the background every 10 ms instead of every second and the values are still exactly the same after 40000 swaps (roughly 10 hours equivalent time if I'm not mistaken). The GTK version I use is 2.12.9.1209.9. Quote:
Note that this is only about virtual memory. The RAM might be recovered after a while regardless of how memory is allocated/free'd. Quote:
Quote:
How was the RES column at startup ? |
Quote:
Quote:
|
All times are GMT -5. The time now is 04:22 PM. |