gtkmm/c ++第一个hello world示例泄漏内存

lfx*_*ove 7 c++ memory memory-leaks gtkmm

我正在尝试学习gtkmm,并决定暂时尝试gtkmm 2.4,因为看起来很难让3.0在Debian上工作.无论如何,我正在尝试的例子是:http://developer.gnome.org/gtkmm-tutorial/2.24/sec-helloworld.html.en.它编译得很好,并且运行正常,但是当我关闭它时,valgrind会报告很多泄漏,这与此类似(点击按钮一次后):

==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)
Run Code Online (Sandbox Code Playgroud)

如果我使用Cc停止程序或单击关闭窗口按钮(在这种情况下我必须使用Shift-Meta-C关闭窗口,因为窗口管理器),会发生这种情况.这是MySQL的连接器之类的预期行为,它不允许您删除最后一个指针吗?在这种情况下,似乎很多内存不被"允许"删除?或者我只是错过了一些非常简单的东西?

为了它,这里是我的代码:(改变HelloWorld测试)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;
}
Run Code Online (Sandbox Code Playgroud)

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;
};
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

提前致谢!

Bra*_*ady 3

考虑到您没有动态内存分配,泄漏并非来自您的代码。由于您在堆栈上定义Test t变量而不是动态定义的,因此当它超出范围时它将被删除。那是 main() 函数完成时,实际上是在整个程序完成之前。Test 类也没有任何直接的动态内存分配。我所说的直接是指直接在该类中,而不是在它包含的属性(gtk 等)中。

为了证明您的测试实例确实被删除,您可以在析构函数中放置一个 printf 。当应用程序退出时,您应该看到输出。

即使您动态定义/创建了测试实例,您也应该养成始终删除您创建的所有内容的习惯。在这种情况下,它只是内存,但它可能是更有价值的资源,例如数据库连接、文件系统资源或需要在退出时执行的一些其他逻辑。

Valgrind 可以为您提供实际内存泄漏发生位置的堆栈跟踪,我很确定您会看到它们在 gtk 代码中。如果是这样,我会考虑提出一个错误。我不会太关心内存still reachable(它实际上不是泄漏),而是查看definitely lostindirectly lost