Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用SDL_图像保存PNG时出现SEGFULT_C_Segmentation Fault_Gdb_Sdl 2_Sdl Image - Fatal编程技术网

C 使用SDL_图像保存PNG时出现SEGFULT

C 使用SDL_图像保存PNG时出现SEGFULT,c,segmentation-fault,gdb,sdl-2,sdl-image,C,Segmentation Fault,Gdb,Sdl 2,Sdl Image,我必须使用SDL2和SLD2_图像在C中创建OCR macOS上的一切都很好。但是,在Linux上运行程序时,在保存PNG文件时会出现SEGFULT 我试图更新我使用的库(SDL2、SDL2_image和libpng),但只能保存一个黑色图像,并在IMG_QUIT()或SDL_QUIT()上获得一个segfault 所以我的代码在IMG\u SavePNG(surface,“textmono.png”) 我也试过了 SDL_SaveBMP(surface, "textmono.bmp") 得到

我必须使用SDL2和SLD2_图像在C中创建OCR

macOS上的一切都很好。但是,在Linux上运行程序时,在保存PNG文件时会出现SEGFULT

我试图更新我使用的库(SDL2、SDL2_image和libpng),但只能保存一个黑色图像,并在IMG_QUIT()或SDL_QUIT()上获得一个segfault

所以我的代码在
IMG\u SavePNG(surface,“textmono.png”)

我也试过了

SDL_SaveBMP(surface, "textmono.bmp")
得到了同样的结果

这是我的代码:

void BlackAndWhite(SDL_Surface* surface){
    Uint32 *pixels = (Uint32 *)surface->pixels;
    for(int i = 0; i < surface->h; i++){
        for(int j = 0; j < surface->w;j++){
            Uint8 red = 0;
            Uint8 green = 0;
            Uint8 blue = 0;
            SDL_GetRGB(pixels[i*surface->w + j], surface->format, &red, &green, &blue);
            Uint8 black = (red + green + blue)/3;
            pixels[i*surface->w + j] = SDL_MapRGB(surface->format, black, black, black);
        }
    }
    IMG_SavePNG(surface, "textbw.png");
}
GDB给了我这个:

Thread 1 "main" received signal SIGSEGV, Segmentation fault.
0x00007ffff7cc947d in _int_malloc (av=av@entry=0x7ffff7e16c40 <main_arena>, 
    bytes=bytes@entry=1304) at malloc.c:3880
3880    malloc.c: Aucun fichier ou dossier de ce type.
(gdb) where
    0x00007ffff7cc947d in _int_malloc (
    av=av@entry=0x7ffff7e16c40 <main_arena>, bytes=bytes@entry=1304)
    at malloc.c:3880
   0x00007ffff7ccacaa in __GI___libc_malloc (bytes=1304) at malloc.c:3073
   0x00007ffff3894e74 in png_malloc_warn ()
   from /lib/x86_64-linux-gnu/libpng16.so.16
   0x00007ffff388ec41 in ?? () from /lib/x86_64-linux-gnu/libpng16.so.16
   0x00007ffff38ab88e in png_create_write_struct_2 ()
   from /lib/x86_64-linux-gnu/libpng16.so.16
   0x00007ffff38ab931 in png_create_write_struct ()
   from /lib/x86_64-linux-gnu/libpng16.so.16
   0x00007ffff7e47d88 in IMG_SavePNG_RW_libpng (surface=0x5555558c9f00, 
    dst=0x5555557fca40, freedst=1) at IMG_png.c:544
    0x000055555555531f in BlackAndWhite (surface=0x5555558c9f00) at main.c:60
   0x00005555555554d0 in loadimage () at main.c:38
   0x0000555555555116 in main () at main.c:21
删除代码的这一部分确实解决了问题,所以我想我找到了问题所在,但我不知道这行代码到底出了什么问题

GDB给了我这个:

Thread 1 "main" received signal SIGSEGV, Segmentation fault.
0x00007ffff7cc947d in _int_malloc (av=av@entry=0x7ffff7e16c40 <main_arena>, 
    bytes=bytes@entry=1304) at malloc.c:3880
3880    malloc.c: Aucun fichier ou dossier de ce type.
(gdb) where
    0x00007ffff7cc947d in _int_malloc (
    av=av@entry=0x7ffff7e16c40 <main_arena>, bytes=bytes@entry=1304)
    at malloc.c:3880
   0x00007ffff7ccacaa in __GI___libc_malloc (bytes=1304) at malloc.c:3073
   0x00007ffff3894e74 in png_malloc_warn ()
   from /lib/x86_64-linux-gnu/libpng16.so.16
   0x00007ffff388ec41 in ?? () from /lib/x86_64-linux-gnu/libpng16.so.16
   0x00007ffff38ab88e in png_create_write_struct_2 ()
   from /lib/x86_64-linux-gnu/libpng16.so.16
   0x00007ffff38ab931 in png_create_write_struct ()
   from /lib/x86_64-linux-gnu/libpng16.so.16
   0x00007ffff7e47d88 in IMG_SavePNG_RW_libpng (surface=0x5555558c9f00, 
    dst=0x5555557fca40, freedst=1) at IMG_png.c:544
    0x000055555555531f in BlackAndWhite (surface=0x5555558c9f00) at main.c:60
   0x00005555555554d0 in loadimage () at main.c:38
   0x0000555555555116 in main () at main.c:21
malloc
free
内的任何崩溃通常(99.9%的时间)意味着堆损坏(例如,堆分配内存溢出,
释放
两次,释放未分配内存等)

这样的bug很难找到,尤其是当您使用第三方库并且不太了解它们的需求时

幸运的是,有一些工具使得发现和理解这些bug变得更加容易:和


使用其中一个,错误可能会很明显。如果不是,您可以使用所用工具的输出编辑您的问题,您可能会得到更好的答案。

好的,所以我使用了另一种获取和设置像素的方法,现在一切似乎都正常了。。。我的代码现在如下所示:

void BlackAndWhite(SDL_Surface* surface){
    int i = 0;
    int j = 0;
    for(i = 0; i < surface->h; i++){
        for(j = 0; j < surface->w;j++){
            Uint8 red = 0;
            Uint8 green = 0;
            Uint8 blue = 0;
            Uint32 pixel = getpixel(surface,j,i);
            SDL_GetRGB(pixel, surface->format, &red, &green, &blue);
            Uint8 black = (red + green + blue)/3;
            pixel = SDL_MapRGB(surface->format, black, black, black);
            putpixel(surface,j,i,pixel);
        }
    }
    IMG_SavePNG(surface, "textbw.png");
}

在本页上对应的功能:

崩溃发生在main.c文件的第60行,该行位于您未显示的函数
BlackAndWhite
中。我的错,我删除了BlackAndWhite,以查看它是否能解决问题,但没有。错误是相同的。黑白和单色的唯一区别是黑白可以生成灰度图像,不管怎样,我将替换问题中的代码。感谢您的回复更新:它使用SDL_图像文档中的“lena.png”来“工作”(图片上有一些奇怪的水平线,但不会崩溃),可能是因为图片是512x512,请花一些时间阅读。请学习如何创建一个向我们展示的工具,最好是一个我们可以复制粘贴并尝试自己复制崩溃的工具。非常感谢,找到合适的工具通常很复杂,我将尝试这个
void BlackAndWhite(SDL_Surface* surface){
    int i = 0;
    int j = 0;
    for(i = 0; i < surface->h; i++){
        for(j = 0; j < surface->w;j++){
            Uint8 red = 0;
            Uint8 green = 0;
            Uint8 blue = 0;
            Uint32 pixel = getpixel(surface,j,i);
            SDL_GetRGB(pixel, surface->format, &red, &green, &blue);
            Uint8 black = (red + green + blue)/3;
            pixel = SDL_MapRGB(surface->format, black, black, black);
            putpixel(surface,j,i,pixel);
        }
    }
    IMG_SavePNG(surface, "textbw.png");
}
putpixel 
getpixel