Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gtkmm/c++ first hello world example leaking memory

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!

like image 525
lfxgroove Avatar asked May 17 '12 16:05

lfxgroove


People also ask

What causes memory leaks in C C++?

Memory leakage occurs in C++ when programmers allocates memory by using new keyword and forgets to deallocate the memory by using delete() function or delete[] operator. One of the most memory leakage occurs in C++ by using wrong delete operator.

What is a memory leak give an example how it can be avoided?

The memory leak occurs, when a piece of memory which was previously allocated by the programmer. Then it is not deallocated properly by programmer. That memory is no longer in use by the program. So that place is reserved for no reason. That's why this is called the memory leak.

What happens when memory leak in C?

A memory leak in C typically happens when the pointer loses its initial allocated address due to which the pointed memory block cannot be accessed or cannot de-allocated, and this becomes the reason for the memory leaks.


2 Answers

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.

like image 130
Brady Avatar answered Sep 30 '22 11:09

Brady


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.

like image 32
baol Avatar answered Sep 30 '22 12:09

baol