我正在开发一个用 GTK+ 用 C 语言编写的相当简单的应用程序,该应用程序内存泄漏严重。它在定时器上有一些基本功能,用于检查时钟并轮询外部网络设备,解析返回的字符串。该应用程序在一个小型触摸板上运行,通过 TOP 我可以看到可用内存在运行时被耗尽。
我对 C 还很陌生,所以我做错了什么并不奇怪,我只是似乎不知道是什么。我一直在尝试使用 Valgrind 来缩小范围,但老实说,输出有点超出了我的想象(运行应用程序不到一分钟生成了 10k+ 行日志文件)。但在挖掘该日志时,我确实发现一些函数反复出现永久丢失的 block ,所有函数都使用一些类似的结构。
示例 1: 这是一个简短的函数,当选择一个选项时会调用它。 g_strdup_printf 的最后一行是 Valgrind 调用的。 select_next_show 和 select_show_ Five_displayed 都是全局变量。
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;
}
在所有像这些导致问题的情况下,我都会释放一切可能的东西,而不会导致段错误,但我一定是错过了其他东西或做错了什么。
更新: 为了回答评论中的问题,以下是我如何使用解析函数以及释放返回值的示例(精简):
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”,但你已经为该释放做了多次分配 - 你多次调用 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);
关于c - 分割和复制字符串导致内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23935722/