7

I'm trying to learn gtkmm, and decided to try gtkmm 2.4 for the time being since it seems to be pretty hard to get 3.0 working on Debian. Anyway, the example I'm trying is the one here: http://developer.gnome.org/gtkmm-tutorial/2.24/sec-helloworld.html.en. It compiles fine and it runs alright aswell, but when i close it valgrind reports a lot of leaks, something along the lines of this (after clicking the button once):

==4254== Memcheck, a memory error detector
==4254== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==4254== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==4254== Command: ./bin/jmb
==4254== 
Hello World
==4254== 
==4254== HEAP SUMMARY:
==4254==     in use at exit: 942,940 bytes in 7,968 blocks
==4254==   total heap usage: 14,191 allocs, 6,223 frees, 3,272,961 bytes allocated
==4254== 
==4254== LEAK SUMMARY:
==4254==    definitely lost: 2,620 bytes in 6 blocks
==4254==    indirectly lost: 5,936 bytes in 187 blocks
==4254==      possibly lost: 358,625 bytes in 1,775 blocks
==4254==    still reachable: 575,759 bytes in 6,000 blocks
==4254==         suppressed: 0 bytes in 0 blocks
==4254== Rerun with --leak-check=full to see details of leaked memory
==4254== 
==4254== For counts of detected and suppressed errors, rerun with: -v
==4254== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 9 from 9)

This happens if i stop the program with C-c or click the close window button (in this case i have to use Shift-Meta-C to close the window because of the window manager). Is this the expected behaviour like MySQL's connector that doesn't allow you to delete that one last pointer? In that case it seems like a lot of memory not being "allowed" to be deleted? Or am i just missing something really simple?

For the sake of it here's my code: (Changed HelloWorld to Test) main.cpp:

#include "gui/Test.hpp"
#include <gtkmm/main.h>
int main(int argc, char **argv)
{
  Gtk::Main kit(argc, argv);
  Test t;
  Gtk::Main::run(t);
  return 0;
}

Test.hpp:

#pragma once

#include <gtkmm/button.h>
#include <gtkmm/window.h>

class Test
  : public Gtk::Window
{
public:
  Test();
  virtual ~Test();

protected:
  //Signal handlers:
  void on_button_clicked();

  //Member widgets:
  Gtk::Button m_button;
};

Test.cpp:

#include "Test.hpp"
#include <iostream>

Test::Test()
  : m_button("Hello World")   // creates a new button with label "Hello World".
{
  // Sets the border width of the window.
  set_border_width(10);

  // When the button receives the "clicked" signal, it will call the
  // on_button_clicked() method defined below.
  m_button.signal_clicked().connect(sigc::mem_fun(*this,
              &Test::on_button_clicked));

  // This packs the button into the Window (a container).
  add(m_button);

  // The final step is to display this newly created widget...
  m_button.show();
}

Test::~Test()
{

}

void Test::on_button_clicked()
{
  std::cout << "Hello World" << std::endl;
}

Thanks in advance!

lfxgroove
  • 3,778
  • 2
  • 23
  • 33
  • Not a proper answer to your gtk question, but in general when investigating memory leaks use `valgrind --leak-check=full --leak-resolution=high --track-origins=yes` to get more detail. – Jonathan Wakely May 17 '12 at 18:35
  • that gives me too much info to be able to process it. should i add a link to the output? – lfxgroove May 18 '12 at 10:25
  • 1
    I suggest you examine it carefully and understand it, it will be useful and a valuable exercise that will help you in future. Someone else could interpret it for you but if they can do it then so can you. You could remove `--leak-resolution=high` to reduce the output, if that helps. – Jonathan Wakely May 18 '12 at 15:47
  • It would seem that the errors mostly originate from libpango, libgobject and libcairo. Might it be my window handler? – lfxgroove May 18 '12 at 18:51
  • It's not the window handler, i just tried with gnome and awesome, same leaks on both of them. – lfxgroove May 18 '12 at 18:58

3 Answers3

3

The leak is not from your code, considering you have no dynamic memory allocations. Since you defined your Test t variable on the stack and not dynamically, it will be deleted when it goes out of scope. That would be when the main() function completes, which is actually before the entire program completes. Nor does the Test class have any direct dynamic memory allocations. By mentioning direct I mean directly in that class, but not in the attributes (gtk, etc) it contains.

To demonstrate that your Test instance is indeed being deleted, you can put a printf in the destructor. You should see the output when the application exits.

Even if you had defined/created the Test instance dynamically, you should get into the habit of always deleting everything you create. In this case its just memory, but it could be more valuable resources like DB connections, File System resources, or some other logic that needs to be executed at exit.

Its possible for Valgrind to give you stack traces of where the actual memory leaks happen, Im pretty sure you'll see that they are in the gtk code. If so, I would consider raising a bug. I wouldnt be too concerned about the still reachable memory (its not actually a leak), but instead look into the definitely lost and indirectly lost.

Brady
  • 10,207
  • 2
  • 20
  • 59
  • Could you please explain why still reachable isn't an actual leak or point me to some resources as to why that is? Also, i've ran Valgrind with --show-origin=yes and it shows most of the to be gtk but also cairo and pango, should i file bug reports there aswell? Thanks in advance! – lfxgroove May 27 '12 at 18:47
  • @Anton, a memory leak is memory to which you no longer have access, meaning you had a pointer to the memory, then without freeing the memory, you assign a different value to the pointer, thus "losing" its address. Still reachable memory is memory that is still referenced by a pointer, and the program terminates, so the memory is not "lost". As for the bugs, I would say yes, but it may be that gtk is not correctly managing those libraries, so they may reject it. When you files the bugs, show the Valgrind stacktrace, they will appreciate it :) – Brady May 27 '12 at 19:48
  • @Anton, I should mention that "Still Reachable" is not as serious as a leak, but ideally it should still be addressed. – Brady May 28 '12 at 05:35
2

Assuming Gtk-- does not leak memory, the output you posted can be compatible with this assumption.

The fact that some memory is still reachable on program exit is not the same thing as a memory leak.

Does the following program leak memory?

int main() {
     int* a = new int[10];
     return 0;
}

It may seem so, but the complete answer should be: It depends!

If we are not using MS/DOS and "a" is needed till the very end of the program, this can be hardly defined a leak... we can say that the programmer left the responsibility for clean up to the underlying operating system.

Moreover Valgrind is a very good and useful tool, but can report false positives.

baol
  • 4,362
  • 34
  • 44
  • So what you're saying is they can't/won't clean up the last pieces of memory and leave that to the underlying os? Is there some kind of documentation on this? Also, is that usual? – lfxgroove May 23 '12 at 14:24
  • I was making a general remark, I cannot speak for the gtkmm developers. I think the right place to ask what they intended to do is their mailing list. – baol Jun 09 '12 at 08:15
1

Set G_SLICE environment variable to reconfigure the GSlice memory allocator.

G_SLICE=always-malloc ./your_application

Look at this post for details.

Szilárd Pfeiffer
  • 1,636
  • 1
  • 12
  • 6
  • I tried both G_SLICE=always-malloc and G_DEBUG=gc-friendly[,resident-modules] it didn't help much, downloaded the mentioned suppress file, it suppressed some of the errors it seems. – lfxgroove May 18 '12 at 18:49