GraphicsMagick 的 OpenCL 开发记录(十三)

文章目录

  • 一个低级错误引发的`core dumped`

<2022-03-30 Wed>

一个低级错误引发的core dumped

当将图片不断缩小到宽高为1x1时会出现如下问题:

gm: magick/image.c:1407: DestroyImage: Assertion `image->signature == MagickSignature' failed.
Aborted (core dumped)

这是因为在ComputeResizeImage()函数中当缩小到1x1时失败,outputReady0导致DestroyImage(filteredImage);的调用,但是在销毁filteredImage后并没有将其赋0导致。

看了一下GraphicsMagick的源码:

/*
  Free memory and set pointer to NULL
*/
#define MagickFreeMemory(memory) \
{ \
  void *_magick_mp=memory;      \
  MagickFree(_magick_mp);       \
  memory=0;                     \
}

这里明明将传入的指针赋0了。难道这段代码不起作用?

其实这个宏是有作用的,但要看怎么使用它。因为DestroyImage()是函数调用,实际上传入的指针是一个副本,将副本赋0并不影响原来的值,同时也要理解宏和函数调用的不同,这里有两种情况需要考虑:

有如下测试代码:

#include 
#include 

typedef void (*MagickFreeFunc)(void *ptr);
static MagickFreeFunc FreeFunc = free;

void MagickFree(void *memory) {
  if (memory != (void *)NULL)
    (FreeFunc)(memory);
}

#define MagickFreeMemory(memory)                \
  {                                             \
    printf("&memory: %p\n", &memory);           \
    printf(" memory: %p\n", memory);            \
    void *_magick_mp = memory;                  \
    MagickFree(_magick_mp);                     \
    memory = 0;                                 \
  }

void destroy_image(char *image) { MagickFreeMemory(image); }

int main() {
  char *image = (char *)malloc(1024);
  printf("&image : %p\n", &image);
  printf(" image : %p\n", image);
  destroy_image(image);
  printf("&image : %p\n", &image);
  printf(" image : %p\n", image);
  return 0;
}

这是GraphicsMagick中的代码使用方式,输出如下:

% ./a.out
&image : 0x7ffc8a46dfb0
 image : 0x55711df782a0
&memory: 0x7ffc8a46df88
 memory: 0x55711df782a0
&image : 0x7ffc8a46dfb0
 image : 0x55711df782a0

这里指针并没有变化,因为是函数调用,如果将代码中的destroy_image()改为宏MagickFreeFunc,则是想要的效果:

#include 
#include 

typedef void (*MagickFreeFunc)(void *ptr);
static MagickFreeFunc FreeFunc = free;

void MagickFree(void *memory) {
  if (memory != (void *)NULL)
    (FreeFunc)(memory);
}

#define MagickFreeMemory(memory)                \
  {                                             \
    printf("&memory: %p\n", &memory);           \
    printf(" memory: %p\n", memory);            \
    void *_magick_mp = memory;                  \
    MagickFree(_magick_mp);                     \
    memory = 0;                                 \
  }

void destroy_image(char *image) { MagickFreeMemory(image); }

int main() {
  char *image = (char *)malloc(1024);
  printf("&image : %p\n", &image);
  printf(" image : %p\n", image);
  MagickFreeMemory(image);
  printf("&image : %p\n", &image);
  printf(" image : %p\n", image);
  return 0;
}
% ./a.out
&image : 0x7ffd7247ae08
 image : 0x5572b59cf2a0
&memory: 0x7ffd7247ae08
 memory: 0x5572b59cf2a0
&image : 0x7ffd7247ae08
 image : (nil)

所以要想解决这个core dumped的问题,就老老实实地按照GraphicsMagick的代码风格,调用完DestroyImage()后再紧接着赋一次0,见commit:fix core dumped。
GraphicsMagick 的 OpenCL 开发记录(十三)_第1张图片

你可能感兴趣的:(c++,开发语言,GraphicsMagick,OpenCL)