一次GTK程序内存泄露的解决过程发现的两个内存泄露的问题

    集成测试的时候发现一个程序在持续的运行过程中有缓慢的内存增长。用ValGrind来查并没有太多的发现。询问开发人员的时候,他说GTK的内存好象都有一些泄露,网上有文曰

If GtkFoo isn't a toplevel window, then

 foo = gtk_foo_new ();
gtk_widget_destroy (foo);

is a memory leak。

 

   这个我是不相信的,于是有了两个内存泄露的问题需要解释。

 

1、我们的程序为什么内存泄露?在放弃了工具帮忙后,逐段代码注释,注释后并细心观察内存半个小时后记录内存起伏情况。最后发现我们的代码确实有问题。

                GList *list_child;

                ......

                list_child=gtk_container_get_children (GTK_CONTAINER (button));
                fixed=GTK_WIDGET(list_child->data);

                list_child=gtk_container_get_children (GTK_CONTAINER (fixed));
                image=GTK_WIDGET(list_child->data);
               
                shadow=button_array_item->shadow;

 

   我们想当然认为list_child不用释放,是容器内部管理的GList列表,实际上,文档明确说返回值是一个newly-allocated的list :

gtk_container_get_children ()

GList

*              gtk_container_get_children          (GtkContainer

 *container);

Returns the container's non-internal children. See gtk_container_forall() for details on what constitutes an "internal" child.

 

container  :

a GtkContainer

Returns  :

a newly-allocated list of the container's non-internal children.

 

2、同事说的例子为什么有内存泄露?找了文章看到下面的解释

 

1.5.

Why does my program leak memory, if I destroy a widget immediately after creating it ?

 

If GtkFoo isn't a toplevel window, then

 foo = gtk_foo_new ();
gtk_widget_destroy (foo);

is a memory leak, because no one assumed the initial floating reference. If you are using a widget and you aren't immediately packing it into a container, then you probably want standard reference counting, not floating reference counting.

To to get this, you must acquire a reference to the widget and drop the floating reference (“ref and sink ” in GTK+ parlance) after creating it:

 foo = gtk_foo_new ();
g_object_ref (foo);
gtk_object_sink (GTK_OBJECT (foo));

When you want to get rid of the widget, you must call gtk_widget_destroy() to break any external connections to the widget before dropping your reference:

 gtk_widget_destroy (foo); 
g_object_unref (foo);

When you immediately add a widget to a container, it takes care of assuming the initial floating reference and you don't have to worry about reference counting at all ... just call gtk_widget_destroy() to get rid of the widget.

 

 

 

  
  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值