首页 > 解决方案 > 自由变量时如何避免libpng中的自由损坏

问题描述

我在 C 中使用 libpng 来加载 png 图像并检索像素数据。

我的代码依赖于那个例子:

http://zarb.org/~gc/html/libpng.html

我修改代码以检索数组中的像素数据:

  int total_size = 0;
  row_pointers   = (png_bytep*) malloc(sizeof(png_bytep) * image->height);
  int* line_size = (int*) malloc(sizeof(int) * image->height);
  for (unsigned int y = 0; y < image->height; y++) {
    int pixel_row_nb = png_get_rowbytes(png, info);
    printf("malloc %d \n", pixel_row_nb);
    total_size += pixel_row_nb;
    line_size[y]    = pixel_row_nb;
    row_pointers[y] = (png_bytep) malloc(pixel_row_nb * sizeof(png_byte));
  }
  printf("total %d vs %d \n", total_size, image->height * image->width * 4);

  png_set_bgr(png);

  png_read_image(png, row_pointers);
  png_destroy_read_struct(&png, &info, NULL);
  fclose(fp);

  for (unsigned int y = 0; y < image->height; y++) {
    if (y == 0) {
      strncpy((void*) image->data, (void*) row_pointers[y], line_size[y]);
    } else {
      strncat((void*) image->data, (void*) row_pointers[y], line_size[y]);
    }
  }

  // Now release png data
  for (unsigned int y = 0; y < image->height; y++) { free(row_pointers[y]); } /// CRASH
  free(row_pointers);

我在前面提到的那条线上遇到了一个损坏错误:

Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51  ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) where
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007ffff6eb48b1 in __GI_abort () at abort.c:79
#2  0x00007ffff6efd907 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7ffff702adfa "%s\n")
    at ../sysdeps/posix/libc_fatal.c:181
#3  0x00007ffff6f0497a in malloc_printerr (str=str@entry=0x7ffff702cad0 "double free or corruption (out)")
    at malloc.c:5350
#4  0x00007ffff6f0bee5 in _int_free (have_lock=0, p=0x555557059aa0, av=0x7ffff725fc40 <main_arena>)
    at malloc.c:4278
#5  __GI___libc_free (mem=0x555557059ab0) at malloc.c:3124
#6  0x000055555556665f in utils_image_load (image=0x55555702c190, 
    image_path=0x7fffffffc2d0 "/home/xav/data/image.png") at src/utils.c:216

我真的不明白为什么。我首先注意到,线宽不相等。正常吗?这就是我添加 line_size 数组的原因。首先,我认为这是腐败的原因,但不是。

编辑:解决方案

使用 memcpy 代替 strncpy 和 strncat。

标签: cmallocfreelibpng

解决方案


推荐阅读