gtkmm/c++ first hello world example leaking memory

一世执手 提交于 2021-02-07 06:26:10

问题


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!


回答1:


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.




回答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.




回答3:


Set G_SLICE environment variable to reconfigure the GSlice memory allocator.

G_SLICE=always-malloc ./your_application

Look at this post for details.



来源:https://stackoverflow.com/questions/10639715/gtkmm-c-first-hello-world-example-leaking-memory

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!