在GTK程序参考hello world内存泄漏 [英] Memory Leaks in GTK hello_world program

查看:150
本文介绍了在GTK程序参考hello world内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以...我想消除我的GTK + 3方案的某些内存泄漏。我虽然这将是回看一些简单的例子,看看是否有一些清理的东西,我忘了,但文档中提供的参考hello world程序有漏洞也是一个好主意。 (下面Valgrind的输出)。

是这些泄漏可以接受吗?如果是这样,有我应该使用调试程序GTK一些其他的应用程序?

  == == 13717 MEMCHECK,内存错误检测
== == 13717版权所有(C)2002至2012年,和GNU GPL的,Julian Seward写等。
== == 13717 Valgrind的使用,3.8.1和LibVEX;与-h版权信息重新运行
== == 13717命令:./a
== == 13717
你好,世界
== == 13717
== == 13717 HEAP摘要:
== == 13717在退出,使用:1578162在11614字节块
== == 13717总堆的使用情况:45699 allocs,34085的FreeS,6461970字节分配
== == 13717
== == 13717泄漏摘要:
== == 13717失去了肯定:2,560字节的块5
== == 13717间接丧失:6,656字节的块207
== == 13717失去了可能:363228字节1937块
== == 13717尚能访问:在9465块1205718字节
== == 13717燮pressed:0字节0块
== == 13717与重新运行--leak检查=全看到内存泄露的细节
== == 13717
== == 13717侦测到并SUP pressed错误计数,重新运行:-v
== == 13717错误摘要:从0 0上下文错误(SUP pressed:2 2)

code:

 的#include< GTK / gtk.h>/ *这是一个回调函数。数据参数被忽略
 *在本实施例。更下方回调。
 * /
静态无效
print_hello(* GtkWidget的部件,
             gpointer数据)
{
  了g_print(的Hello World \\ n);
}静态gboolean
on_delete_event(* GtkWidget的部件,
                 GdkEvent *事件,
                 gpointer数据)
{
  / *如果返回的delete_event信号处理FALSE,
   GTK会发出destroy信号。返回true手段
   *您不想被破坏的窗口。
   *
   *这是弹出有用的你确定要退出?
   *类型的对话框。
   * /  了g_print(删除事件发生\\ n);  返回TRUE;
}INT
主(INT ARGC,
      的char * ARGV [])
{
  / * GtkWidget的是构件的存储类型* /
  * GtkWidget的窗口;
  * GtkWidget的按钮;  / *这就是所谓的在所有的GTK程序。参数解析
   *从命令行和被返回到应用程序。
   * /
  gtk_init(安培; ARGC,&安培; argv的);  / *创建一个新窗口,并设置其标题* /
  窗口= gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title(GTK_WINDOW(窗口),你好);  / *当窗口发出删除事件信号(它被发射
   *通过GTK +响应于从窗口管理器来的事件,
   *通常是点击关闭窗口控制的结果),我们
   *请它来调用如上定义的on_delete_event()函数。
   *
   *传给回调函数的数据为NULL,将被忽略
   *在回调函数。
   * /
  g_signal_connect(窗口,删除事件,G_CALLBACK(on_delete_event),NULL);  / *在这里,我们的消灭事件连接到gtk_main_quit()函数。
   *
   *当我们在窗口上调用gtk_widget_destroy()这个信号被发射,
   *如果我们在delete_event回调返回FALSE。
   * /
  g_signal_connect(窗口,消灭,G_CALLBACK(gtk_main_quit),NULL);  / *设置窗口的边框宽度。 * /
  gtk_container_set_border_width(GTK_CONTAINER(窗口),10);  / *创建带标签的Hello World的新按钮。 * /
  按钮= gtk_button_new_with_label(的Hello World);  / *当按钮收到点击信号,它会调用
   *功能print_hello()将其传递NULL作为参数。
   *
   *本print_hello()函数定义如上。
   * /
  g_signal_connect(按钮,点击,G_CALLBACK(print_hello),NULL);  / *该函数g_signal_connect_swapped()函数将连接点击信号
   按钮的gtk_widget_destroy()函数的*;与其说这
   *使用按钮作为参数,它会与用户数据交换它
   *参数。这将导致通过调用销毁窗口
   * gtk_widget_destroy()在窗口上。
   * /
  函数g_signal_connect_swapped(按钮,点击,G_CALLBACK(gtk_widget_destroy),窗口);  / *这个包中的按钮到窗口。一个从GtkWindow窗口继承GtkBin,
   *这是一个特殊的容器,它只能有一个孩子
   * /
  gtk_container_add(GTK_CONTAINER(窗口),按钮);  / *最后一步是显示这些新插件创建... * /
  gtk_widget_show(按钮);  / * ...和窗口* /
  gtk_widget_show(窗口);  / *所有的GTK程序必须有一个gtk_main()函数。控制到此为止
   *并等待事件发生(如键preSS或鼠标事件),
   *直到gtk_main_quit()被调用。
   * /
  进入主循环();  返回0;
}


解决方案

这个回答是从回答同一个问题上编译www.gtkfourms.com。

http://www.gtkforums.com/viewtopic.php? F = 3& T公司= 178517 (用户埃罗尔)


  

GTK +是pretty懒散,当涉及到分配和释放所需应用程序的生命时间内部缓冲区。例如,它可以是所需要的应用程序的生命初始化期间分配的内存的查找表的区域。那么GTK +将永远不会释放这一点。要Valgrind的这看起来像一个内存泄漏,(这在技术上是),但作为优化GTK +不释放它,因为它会在应用程序退出被释放,因此不是一个错误。这就是为什么你需要燮pression文件,以便Valgrind的可以忽略这些。问题是,你将需要与大多数GTK +版本的改变来改变这些。


燮的pression文件库:
https://github.com/dtrebbien/GNOME.supp

克隆库后,可以生成燮pression文件(还附带了巧舌如簧,GDK,和其他人)与让,然后Valgrind的引用它们像这样:

 的valgrind ./a --sup pression = /路径/要/ gtk3.supp

So... I'm trying to eliminate some memory leaks from my GTK+ 3 program. I though it would be a good idea to look back at some simple examples to see if there is some cleanup stuff I'm forgetting, but the hello_world program provided in the documentation has leaks too. (Valgrind output below).

Are these leaks acceptable? If so, is there some other application I should be using to debug GTK programs?

==13717== Memcheck, a memory error detector
==13717== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==13717== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==13717== Command: ./a
==13717== 
Hello World
==13717== 
==13717== HEAP SUMMARY:
==13717==     in use at exit: 1,578,162 bytes in 11,614 blocks
==13717==   total heap usage: 45,699 allocs, 34,085 frees, 6,461,970 bytes allocated
==13717== 
==13717== LEAK SUMMARY:
==13717==    definitely lost: 2,560 bytes in 5 blocks
==13717==    indirectly lost: 6,656 bytes in 207 blocks
==13717==      possibly lost: 363,228 bytes in 1,937 blocks
==13717==    still reachable: 1,205,718 bytes in 9,465 blocks
==13717==         suppressed: 0 bytes in 0 blocks
==13717== Rerun with --leak-check=full to see details of leaked memory
==13717== 
==13717== For counts of detected and suppressed errors, rerun with: -v
==13717== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

Code:

#include <gtk/gtk.h>

/* This is a callback function. The data arguments are ignored
 * in this example. More on callbacks below.
 */
static void
print_hello (GtkWidget *widget,
             gpointer   data)
{
  g_print ("Hello World\n");
}

static gboolean
on_delete_event (GtkWidget *widget,
                 GdkEvent  *event,
                 gpointer   data)
{
  /* If you return FALSE in the "delete_event" signal handler,
   * GTK will emit the "destroy" signal. Returning TRUE means
   * you don't want the window to be destroyed.
   *
   * This is useful for popping up 'are you sure you want to quit?'
   * type dialogs.
   */

  g_print ("delete event occurred\n");

  return TRUE;
}

int
main (int   argc,
      char *argv[])
{
  /* GtkWidget is the storage type for widgets */
  GtkWidget *window;
  GtkWidget *button;

  /* This is called in all GTK applications. Arguments are parsed
   * from the command line and are returned to the application.
   */
  gtk_init (&argc, &argv);

  /* create a new window, and set its title */
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_window_set_title (GTK_WINDOW (window), "Hello");

  /* When the window emits the "delete-event" signal (which is emitted
   * by GTK+ in response to an event coming from the window manager,
   * usually as a result of clicking the "close" window control), we
   * ask it to call the on_delete_event() function as defined above.
   *
   * The data passed to the callback function is NULL and is ignored
   * in the callback function.
   */
  g_signal_connect (window, "delete-event", G_CALLBACK (on_delete_event), NULL);

  /* Here we connect the "destroy" event to the gtk_main_quit() function.
   *
   * This signal is emitted when we call gtk_widget_destroy() on the window,
   * or if we return FALSE in the "delete_event" callback.
   */
  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);

  /* Sets the border width of the window. */
  gtk_container_set_border_width (GTK_CONTAINER (window), 10);

  /* Creates a new button with the label "Hello World". */
  button = gtk_button_new_with_label ("Hello World");

  /* When the button receives the "clicked" signal, it will call the
   * function print_hello() passing it NULL as its argument.
   *
   * The print_hello() function is defined above.
   */
  g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);

  /* The g_signal_connect_swapped() function will connect the "clicked" signal
   * of the button to the gtk_widget_destroy() function; instead of calling it
   * using the button as its argument, it will swap it with the user data
   * argument. This will cause the window to be destroyed by calling
   * gtk_widget_destroy() on the window.
   */
  g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window);

  /* This packs the button into the window. A GtkWindow inherits from GtkBin,
   * which is a special container that can only have one child
   */
  gtk_container_add (GTK_CONTAINER (window), button);

  /* The final step is to display this newly created widget... */
  gtk_widget_show (button);

  /* ... and the window */
  gtk_widget_show (window);

  /* All GTK applications must have a gtk_main(). Control ends here
   * and waits for an event to occur (like a key press or a mouse event),
   * until gtk_main_quit() is called.
   */
  gtk_main ();

  return 0;
}

解决方案

This answer is compiled from answers to the same question on www.gtkfourms.com.

http://www.gtkforums.com/viewtopic.php?f=3&t=178517 (user errol)

GTK+ is pretty lazy when it comes to allocating and deallocating internal buffers needed for the life time of the application. For example it may allocate an area of memory for a lookup table during initialisation which is needed for the life of the application. GTK+ will then never deallocate this. To Valgrind this looks like a memory leak, (which technically it is) but as an optimisation GTK+ does not deallocate it as it will be deallocated during application exit and so not an error. This is why you need suppression files so that Valgrind can ignore these. The problem is that you will need to change these with most GTK+ version changes.

Repository of suppression files: https://github.com/dtrebbien/GNOME.supp

After cloning the repository, you can generate the suppression files (also comes with glib, gdk, and others) with "make" and then refer valgrind to them like so:

valgrind ./a --suppression=/path/to/gtk3.supp

这篇关于在GTK程序参考hello world内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆