Mem утечка в загрузчике изображений - PullRequest
1 голос
/ 08 июля 2010

У меня есть функция для загрузки GdkPixbufAnimation из потока.

GdkPixbufAnimation* load_image_from_stream(GInputStream* input_stream, GCancellable* generator_cancellable)
{ 
   GError** error; 
 gboolean res;
 gssize n_read;
 guchar buffer[65535];

 GdkPixbufAnimation* animation;
 GdkPixbufLoader*    loader;

 loader = gdk_pixbuf_loader_new();

 res = TRUE;

 while (1)
 {
      n_read = g_input_stream_read (input_stream, buffer, sizeof (buffer), generator_cancellable, error);

   if (n_read < 0)
   {
    res = FALSE;
    error = NULL; 
    g_object_unref(loader);
      break;
   }

   if (n_read == 0)
   {
      break;
    g_object_unref(loader);
   }

   if (!gdk_pixbuf_loader_write (loader, buffer, n_read, error))
   {
    res = FALSE;
    error = NULL;
    g_object_unref(loader);
    break;
   }
 }

 if (!gdk_pixbuf_loader_close (loader, error)) 
 {
  res = FALSE;
  error = NULL;
  return;
 }

 animation = NULL;

 if (res) 
 {
  animation = gdk_pixbuf_loader_get_animation(loader);

  if (animation)
  {
   g_object_ref (animation);
      g_object_unref(loader);
  }
 }

 return animation;
}

Попробуйте назвать эту функцию так:

void loading(JobParam* param)
{   
    GInputStream* input_stream;
    input_stream = g_file_read(param->file, param->generator_cancellable, NULL);
    param->animation = load_image_from_stream(G_INPUT_STREAM(input_stream), param->generator_cancellable);  

    g_input_stream_close(input_stream, param->generator_cancellable, NULL);
    g_object_unref (input_stream);
}

Но когда я пытаюсь вызвать эту функцию, у меня возникает утечка памяти. Зачем? Что не так в реализации функции?

Спасибо

Ответы [ 3 ]

3 голосов
/ 08 июля 2010
  • Ваш отступ (или его отсутствие) делает код невозможным для чтения.Исправьте это, и ошибки, вероятно, будут более очевидными.
  • У вас есть недостижимый код в if (n_read == 0), сразу после этого оператора break.
  • Вы кажетесь непоследовательными в загрузчике free-free.
  • error в никогда не инициализируется, но передается gdk_pixbuf_loader_new.
3 голосов
/ 08 июля 2010

после условия если (n_read == 0) Вы предоставили перерыв в первую очередь. Следовательно, загруженный pixbuff не освобождается. Итак, вы получаете утечку памяти.

Дополнительные баллы:

Вы передаете двойной указатель, а именно error функции

g_input_stream_read 

В этот указатель будут загружены код ошибки и строка ошибки в случае ошибки в API. Пожалуйста, проверьте его, прежде чем присваивать ему значение NULL. Вы можете проверить определение структуры GError здесь. GError Пожалуйста, проверьте значение кода и сообщения, чтобы получить описание ошибки.

Это должно быть сделано и для всех других вызовов API. Надеюсь, это поможет.

3 голосов
/ 08 июля 2010

Операторы в if блоке в правильном порядке?

 if (n_read == 0)
   {
      break;
      g_object_unref(loader);
   }
...