开罗记忆泄漏

时间:2013-05-29 18:24:44

标签: c++ memory memory-leaks cairo

我在下面写了一个drawCircle函数但是随着更多的圆圈被绘制/重绘,内存使用量大大增加,所以我假设某个地方存在内存泄漏,但我似乎无法弄明白。我试过在函数结束时删除实例,但这没有帮助。

void drawCircle(cairo_surface_t *container, int x, int y, int radius, float r, float g, float b, float a)
{   
cairo_t *cairoInstance;                                                                                                                      
cairoInstance = cairo_create(container);                                                                                                                     

cairo_set_source_rgba(cairoInstance, r, g, b, a);
cairo_arc(cairoInstance, x, y, radius, 0, 2*M_PI);
cairo_stroke_preserve(cairoInstance);
cairo_fill_preserve(cairoInstance);

//delete cairoInstance;
gtk_widget_queue_draw_area(GTK_WIDGET(frame2), 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);   
}

有什么想法吗? 提前谢谢。

1 个答案:

答案 0 :(得分:2)

几点:

  • cairo_t被引用计算。完成cairo_t*后,请致电cairo_destroy。或者,您不需要为每个圈创建和销毁cairo_t - 通过拔出对cairo_create的调用来重构该函数。
  • 除非您需要,否则cairo_X函数更喜欢cairo_X_preserve个函数。您的代码cairo_fill_preserve应该是cairo_preserve。 (但应保留笔划,以便以下填充有效。)
  • 使用gtk_widget_queue_draw_area使gtk小部件的矩形无效的调用也可以重构,并且每次绘制只进行一次。
  • gtk_widget_queue_draw_area使窗口小部件窗口的矩形区域无效 - 仅使用gdk_window_invalidate_rect就可以了 - 请参阅the documentation

重构后的伪代码(使用假设的Circle类型):

void drawCircle(cairo_t *cr, int x, int y, int radius, float r, float g, float b, float a) {   
    cairo_set_source_rgba(cr, r, g, b, a);
    cairo_arc(cr, x, y, radius, 0, 2*M_PI);
    cairo_stroke_preserve(cr); // keep the arc so that we can call cairo_fill
    cairo_fill(cr);
}

void functionThatDrawsCircles(cairo_surface_t* surface, Circle* circles, int num) {
    cairo_t* cr = cairo_create(surface);
    for(int i = 0; i < num; i++) {
        drawCircle(cr, circles[i].x, circles[i].y, 10, circles[i].r, circles[i].g, circles[i].b, 1.0);
    }
    cairo_destroy(cr);
    gtk_widget_queue_draw_area(GTK_WIDGET(frame2), 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);   
}