libpng中的内存泄漏?还是我太蠢了?

6

Valgrind提示我的一些代码有问题,但这段代码基本上是从文档中复制的样例libpng代码:

以下是Valgrind输出的示例。

==15847== 14,384 bytes in 31 blocks are definitely lost in loss record 239 of 240
==15847==    at 0x4C28F9F: malloc (vg_replace_malloc.c:236)
==15847==    by 0x5837381: ??? (in /lib/x86_64-linux-gnu/libpng12.so.0.46.0)
==15847==    by 0x581FD63: png_create_info_struct (in /lib/x86_64-linux-gnu/libpng12.so.0.46.0)
==15847==    by 0x67837C: Star::Image::loadPng(char const*) (StarImage.cpp:35)
==15847==    by 0x4E7721: Star::Assets::threadedFetchImage(Star::String const&, bool) (StarAssets.cpp:400)
==15847==    by 0x4EB4F4: Star::Assets::threadPoolMain() (StarAssets.cpp:256)
==15847==    by 0x6B18B9: Star::ThreadImpl::runThread(void*) (StarThread_unix.cpp:19)
==15847==    by 0x5CE2EFB: start_thread (pthread_create.c:304)
==15847==    by 0x6A1359C: clone (clone.S:112)

在第35行左右的代码方法。该行由注释标记,并以png_infop end_info开头。

ImagePtr Image::loadPng(char const* filename) {
  FILE *fp = fopen(filename, "rb");
  if (!fp)
    throw ImageException(strf("Could not open file %s in Image::loadPng", filename));

  png_byte header[8];
  int res = fread(header, 1, sizeof(header), fp);
  if (!res)
    throw ImageException(strf("Cannot read file %s", filename));

  if (png_sig_cmp(header, 0, sizeof(header)))
    throw ImageException(strf("File %s is not a png image!", filename));

  png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
  if (!png_ptr) {
    fclose(fp);
    throw ImageException("Internal libPNG error");
  }

  png_infop info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr) {
    png_destroy_read_struct(&png_ptr, nullptr, nullptr);
    fclose(fp);
    throw ImageException("Internal libPNG error");
  }

  png_infop end_info = png_create_info_struct(png_ptr);  //this is line 35.
  if (!end_info) {
    png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
    fclose(fp);
    throw ImageException("Internal libPNG error");
  }

  if (setjmp(png_jmpbuf(png_ptr))) {
    png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
    fclose(fp);
    throw ImageException("Internal error reading png.");
  }

//snip some

  png_read_image(png_ptr, row_ptrs.get());
  png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)0);
  fclose(fp);

  return image;
}

这与位于http://www.libpng.org/pub/png/libpng-1.2.5-manual.html#section-3的示例几乎相同。

这是内部泄漏吗?还是我错过了一些非常明显的东西?或者Valgrind出现了问题?

供参考,我目前正在使用libpng1.2.46。


4
如果读取失败,你是否应该像之前那样在最后的销毁调用中传递&end_info - Retired Ninja
1个回答

10

最后一行

 png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)0);

不应该是“rather”

 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);

?


谢谢,那正是问题所在。 - OmnipotentEntity

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接