使用SDL_image保存PNG时出现段错误

问题描述 投票:0回答:2

我两周前开始使用C语言(所以我很新),现在我必须使用SDL2和SLD2_image在C语言中为学校创建OCR。在macOS上一切正常。但是,在Linux上运行程序时,保存PNG文件时会出现段错误。

我试图更新我使用的库(SDL2,SDL2_image和libpng),并且只能保存黑色图像并在IMG_QUIT()或SDL_QUIT()上出现段错误

所以我的代码在IMG_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");
}

这是我如何加载我的png文件:

int loadimage(void){
    if(SDL_Init(SDL_INIT_VIDEO)==-1)
    {
        printf("SDL_Init: %s\n", SDL_GetError());
        return 1;
    }
    IMG_Init(~0);
    SDL_Surface *surface =  IMG_Load("text.png");
    if(surface != NULL){
        ...
    }
    else{
        printf("Failed ! %s\n", IMG_GetError());
    }
    return 0;
}

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

EDIT:AddressSanitizer告诉我,

处有堆缓冲区溢出
SDL_GetRGB(pixels[i*surface->w + j], surface->format, &red, &green, &blue)

删除代码的这一部分确实可以解决问题,所以我想我找到了问题,但是我并没有真正理解此行有什么问题...

c segmentation-fault gdb sdl-2 sdl-image
2个回答
0
投票

GDB给我这个:

任何崩溃内部 mallocfree通常(99.9%的时间)表示您有堆损坏(例如,堆分配的内存溢出,free两次,free ing未分配的内存等)。

这类错误很难找到,尤其是当您使用第三方库并且不太了解它们的要求时。

幸运的是,有一些工具使查找和理解此类错误变得更容易:Valgrindaddress sanitizer使用其中之一,该错误可能很明显。如果不是这样,则可以使用所用工具的输出来编辑问题,这样可能会得到更好的答案。


0
投票
好,所以我使用了另一种获取和设置像素的方法,现在一切似乎都可以正常工作了……我的代码现在看起来像这样:
© www.soinside.com 2019 - 2024. All rights reserved.