c -分割和复制字符串导致内存泄漏



我正在用GTK+用C编写一个相当简单的应用程序,该应用程序严重泄漏内存。它在计时器上有一些基本功能,用于检查时钟和轮询外部网络设备,解析返回的字符串。应用程序在一个小的触摸面板上运行,通过TOP我可以看到可用内存在运行时被消耗掉。

我对C很陌生,所以我做错了什么并不奇怪,我只是不知道是什么。我一直在尝试使用Valgrind来缩小它的范围,但老实说,输出有点超出我的理解范围(运行应用程序不到一分钟生成的10k+行日志文件)。但在挖掘日志时,我确实发现一些函数反复出现永久性丢失的块,它们都使用了一些类似的结构。

示例1:这是一个短函数,当选择一个选项时调用。带有g_strdup_printf的最后一行是由Valgrind调用的。Select_next_show和select_show_five_display都是全局变量。

static void show_box_five_clicked ()
{
g_timer_start(lock_timer);
gtk_image_set_from_file (GTK_IMAGE(select_show_1_cb_image), "./images/checkbox_clear.png");
gtk_image_set_from_file (GTK_IMAGE(select_show_2_cb_image), "./images/checkbox_clear.png");
gtk_image_set_from_file (GTK_IMAGE(select_show_3_cb_image), "./images/checkbox_clear.png");
gtk_image_set_from_file (GTK_IMAGE(select_show_4_cb_image), "./images/checkbox_clear.png");
gtk_image_set_from_file (GTK_IMAGE(select_show_5_cb_image), "./images/checkbox_checked.png");
select_next_show = g_strdup_printf("%i",select_show_five_displayed);
}  

示例2:这是另一个经常被调用的函数,在Valgrind日志中经常出现。它接受来自网络设备的传入响应,将其解析为两个字符串,然后返回一个。

static gchar* parse_incoming_value(gchar* incoming_message)
{
gchar *ret;
GString *incoming = g_string_new(incoming_message);
gchar **messagePieces = g_strsplit((char *)incoming->str, "=", 2);
ret = g_strdup(messagePieces[1]);
g_strfreev(messagePieces);
g_string_free(incoming, TRUE);
return ret;
}

在所有像这些导致问题的情况下,我释放了一切,我可以不引起分割错误,但我一定是错过了别的东西或做错了什么。

更新:为了回答评论中的问题,这里有一个示例(经过删节),说明我如何使用parse函数,以及返回值在哪里被释放:

static void load_schedule ()
{
    ...other code...
    gchar *holder;
    gchar *holder2;
    holder = read_a_line(schedListenSocket);
    holder2 = parse_incoming_value(holder);
    schedule_info->regShowNumber = holder2;
    holder = read_a_line(schedListenSocket);
    holder2 = parse_incoming_value(holder);
    schedule_info->holidayShowNumber = holder2;
    ...other code....
    g_free(holder);
    g_free(holder2);
}

任何帮助都是非常感激的!

看起来你在调用g_free(holder2)时释放了一次'ret',但是你已经为那个free做了多次分配-你多次调用parse_incoming_value,每次都导致分配,但是你只在最后释放了一次。

当您每次将holder2指针复制到schedule_info元素时,它们实际上在最后有"泄漏"的内存。

如果您不释放holder2的任何地方,但只是释放schedule_info中的所有元素在代码的末尾。我想这说明没有泄漏吧?

holder2 = <result of dynamic alloc>;
schedule_info->a = holder2;
...
holder2 = <result of dynamic alloc>;
schedule_info->b = holder2;
...
// instead of g_free(holder2) at the end, do this...
g_free(schedule_info->a);
g_free(schedule_info->a);

最新更新