2012-05-31 2 views
0

Я надеюсь, что кто-то может помочь мне разобраться в утечке памяти, которая сводит меня с ума. Через различные раунды устранения неполадок я сузил проблему до одного конкретного раздела одной конкретной функции, которая обновляет метку GTK на основе входящего сетевого сообщения. Эта функция повторяется на таймере каждые 200 мс, пока программа работает. Если нет входящих сетевых сообщений или нет входящих сообщений, которые соответствуют тем, которые я ищу, проблем нет. Но когда я начинаю отправлять сообщения, которые соответствуют, вызывая вызов gtk_label_set_text, я начинаю видеть медленную утечку памяти. Пока совпадают сообщения, память падает ровно на 60 к каждые 30-60 секунд. Если я перестаю отправлять соответствующие сообщения, утечка немедленно прекратится.Утечка памяти из gtk_label_set_text

Вот моя функция:

static gboolean get_incoming_message() 
{ 

gchar *buffer = g_malloc(1024); 
gssize incoming_size; 
GError *err = NULL; 

incoming_size = g_socket_receive(listenSocket, (gchar *)buffer, 1024, NULL, &err); 


if (incoming_size > 0) 
{ 
    gchar *incoming_message = g_strndup ((const gchar *)buffer, incoming_size); 

    if ((g_strcmp0(incoming_message, "Show 1 in Progress")==0) || (g_strcmp0(incoming_message, "Show 2 in Progress")==0)) 
    { 

     gtk_label_set_text (GTK_LABEL (current_status_message_box), (const gchar *)incoming_message); 
    } 

    g_free(incoming_message); 
    g_free(buffer); 
    g_error_free(err); 
    return TRUE; 
} 
else 
{ 
    g_free(buffer); 
    g_error_free(err); 
    return TRUE; 
} 

return FALSE; 

} 

Опять же, утечка происходит только тогда, когда, если заявление с g_strcmp0 в нем принимает значение TRUE.

Надеясь, что кто-то скажет мне, где я ошибаюсь, или если это на самом деле проблема в GTK, есть ли способ обойти это?

Заранее благодарен!

ответ

1

Ваш код страдает от какой-то проблемы:

  1. , если вы не заботитесь обработки ошибок, использовать NULL вместо err;
  2. если err - NULL, это не должно быть g_error_free 'd: на самом деле это работает, но не рассчитывает на это;
  3. если buffer является локальным для вашей функции, просто используйте локальный массив: он будет избегать g_free() на каждой точке выхода;
  4. return FALSE не достигается;

Я бы переписать это так:

static gboolean get_incoming_message() 
{ 
    gchar buffer[1024]; 
    gssize incoming_size; 

    incoming_size = g_socket_receive(listenSocket, buffer, 1024, NULL, NULL); 
    if (incoming_size < 0) 
     return FALSE; 

    if (incoming_size > 0 && 
     (strncmp(buffer, "Show 1 in Progress", 1024) == 0 || 
     strncmp(buffer, "Show 2 in Progress", 1024) == 0)) 
     gtk_label_set_text(GTK_LABEL(current_status_message_box), buffer); 

    return TRUE; 
} 

кроме этого, нет утечки в коде вы публикуемую.

+0

Спасибо, сегодня я попробую попробовать. Но если утечки здесь нет, я не знаю, где еще это может быть, поскольку, похоже, он уходит, когда я прокомментирую вызов этой функции. Может ли быть где-то в создании GSocket listenSocket? Если бы это было так, я бы подумал, что утечка по-прежнему будет возникать, когда появятся входящие сообщения независимо от того, вызвал ли я g_socket_receive ... – DrRocket

+0

Помимо 'g_error_free', ваш код не имеет очевидных ошибок. Мое предположение: 1. у вас нет утечек (то есть, вы проверяете наличие утечек, ошибочны); 2. Вы передаете текст без utf8 в gtk_label_set_text() (не показано в приведенном выше коде); 3. утечка находится где-то в другом месте. – ntd

+0

Addenum: Я только что проверил, что ваш предыдущий код эффективно протекал 'incoming_message'. – ntd

1

Ваше использование gtk_label_set_text() выглядит хорошо.

Это не соответствует вашему описанию на первый взгляд, но я отмечаю, что вы никогда не освобождаете incoming_message, поэтому он будет течь каждый раз, когда будет получено сообщение. Возможно там are Нет сообщений с ненулевым размером, что не соответствует вашему состоянию?

+0

Я действительно думал об этом, но g_free вызывает ошибку, когда я пытаюсь освободить входящее_значение, поскольку это const gchar. У меня создалось впечатление, что контр-гхара не нужно освобождать. Разве это не так? Я знаю, что есть ненулевые сообщения, которые не соответствуют моему состоянию, потому что я вручную отправляю сообщения. Но я уверен, что возможно, что утечка происходит каждый раз, но только проявляется, когда возникает set_text? – DrRocket

+0

Я изменил вещи, чтобы объявить incoming_message как gchar вместо const и теперь освободить его, но я все еще вижу точно такую ​​же утечку, только когда получаются соответствующие сообщения. – DrRocket

+0

@DrRocket - создание переменной 'const' действительно означает компилятор, что вам не нужно освобождать переменную, но' const' является ложью здесь, поскольку строка представляет собой динамическую память, которая действительно должна быть освобождена. Жаль, что это не проблема.Вы пытались запустить с запросом 'gtl_label_set_text()' comment? Из-за этого утечка тоже уходит? –

Смежные вопросы