无法在libpng中使用info_ptr

时间:2019-08-17 10:03:33

标签: c libpng

我正在编写一个读取png文件并将其数据保存到我的类型的代码。它的工作原理很好,但是当我尝试释放info_ptr时,当我不尝试释放info_ptr时会导致错误或导致内存泄漏。要修复它,我仍然不明白为什么会这样。

我尝试过:

png_destroy_read_struct(&png_ptr, &info_ptr, NULL); = munmap_chunk():无效的指针

png_destroy_read_struct(&png_ptr, NULL, NULL); = valgrind泄漏了info_ptr的内存

全功能代码: (我在valgrind的括号中标记了重要的行号)

(106)static int bitmap_from_png_file(bitmap_t* out,char* path){

    int status = -1;

    FILE* fp = fopen(path, "rb");
    if(!fp) goto fopen_failed;

    #define SIG_SIZE 8
    unsigned char sig[SIG_SIZE]; 
    fread(sig, 1, SIG_SIZE, fp);
    if(!png_check_sig(sig, SIG_SIZE)){
        fclose(fp);
        return -2;
    }

    png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,NULL,NULL);
    if (!png_ptr) goto png_create_read_struct_failed;

(124)png_infop info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr)  goto png_create_info_struct_failed;

    if (setjmp(png_jmpbuf(png_ptr))) goto png_failure;

    png_set_sig_bytes(png_ptr, SIG_SIZE);
    png_init_io(png_ptr,fp);
(131)png_read_png(png_ptr,info_ptr,PNG_TRANSFORM_IDENTITY,NULL);

    png_byte** row_pointers = png_get_rows(png_ptr, info_ptr);

    for(size_t y = 0;y<out->height;y++){
        png_byte* row = row_pointers[y];
        for(size_t x = 0; x < out->width;x++){
            write_pixel(out,new_pixel_t(*row++,*row++,*row++),x,y);
        }
    }

    status = 0;

    for(size_t y = 0;y<out->height;y++)
        png_free (png_ptr,row_pointers[y]);
(146)png_free (png_ptr, row_pointers);

    png_failure:
    png_create_info_struct_failed:
(150)   png_destroy_read_struct(&png_ptr,NULL,NULL); /*Function that causing errors*/
    png_create_read_struct_failed:
        fclose (fp);
    fopen_failed:
    return status;
}

当我不尝试释放info_ptr时使用valgrind:

==9176== 392 bytes in 1 blocks are definitely lost in loss record 1 of 1
==9176==    at 0x483877F: malloc (vg_replace_malloc.c:299)
==9176==    by 0x49CDAA3: png_create_info_struct (in /usr/lib/libpng16.so.16.37.0)
==9176==    by 0x10988A: bitmap_from_png_file (main.c:124)
==9176==    by 0x109D5F: main (main.c:197)
==9176== 
==9176== LEAK SUMMARY:
==9176==    definitely lost: 392 bytes in 1 blocks
==9176==    indirectly lost: 0 bytes in 0 blocks
==9176==      possibly lost: 0 bytes in 0 blocks
==9176==    still reachable: 0 bytes in 0 blocks
==9176==         suppressed: 0 bytes in 0 blocks
==9176== 
==9176== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==9176== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
当我尝试释放info_ptr时,

valgrind:

==9401== 1024 errors in context 3 of 3:
==9401== Invalid read of size 8
==9401==    at 0x49CDE3A: png_free_data (in /usr/lib/libpng16.so.16.37.0)
==9401==    by 0x49CE20C: png_destroy_info_struct (in /usr/lib/libpng16.so.16.37.0)
==9401==    by 0x49DA326: png_destroy_read_struct (in /usr/lib/libpng16.so.16.37.0)
==9401==    by 0x109A84: bitmap_from_png_file (main.c:150)
==9401==    by 0x109D63: main (main.c:197)
==9401==  Address 0x5738ef0 is 0 bytes inside a block of size 8,192 free'd
==9401==    at 0x48399AB: free (vg_replace_malloc.c:530)
==9401==    by 0x109A69: bitmap_from_png_file (main.c:146)
==9401==    by 0x109D63: main (main.c:197)
==9401==  Block was alloc'd at
==9401==    at 0x483877F: malloc (vg_replace_malloc.c:299)
==9401==    by 0x49D3C9E: png_malloc (in /usr/lib/libpng16.so.16.37.0)
==9401==    by 0x49DA86F: png_read_png (in /usr/lib/libpng16.so.16.37.0)
==9401==    by 0x109908: bitmap_from_png_file (main.c:131)
==9401==    by 0x109D63: main (main.c:197)
==9401== 
==9401== ERROR SUMMARY: 2049 errors from 3 contexts (suppressed: 0 from 0)

1 个答案:

答案 0 :(得分:0)

免费删除本手册后尝试。我认为这种免费应该自动得到照顾

for(size_t y = 0;y<out->height;y++)
        png_free (png_ptr,row_pointers[y]);
   png_free (png_ptr, row_pointers);