gpt4 book ai didi

c - 在函数内创建渲染器时出现 SDL2 段错误

转载 作者:太空宇宙 更新时间:2023-11-04 01:57:47 24 4
gpt4 key购买 nike

使用 sdl2 库,我试图在一个函数内创建窗口、表面和渲染器,但我一直收到段错误。我在这里有我的 init_display 函数:

void init_display (SDL_Window *window, SDL_Surface *surface, SDL_Renderer *renderer, int window_width, int window_height) {

SDL_Init(SDL_INIT_VIDEO);

window = SDL_CreateWindow("Cellular Automaton", 0, 0, window_width, window_height, SDL_WINDOW_SHOWN);
surface = SDL_GetWindowSurface(window);
renderer = SDL_CreateSoftwareRenderer(surface);

SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderClear(renderer);
}

在执行期间,我的程序然后调用第二个函数,该函数使用刚刚创建的渲染器,特别是 SDL_SetRenderDrawColor

void draw_blocks (SDL_Renderer *renderer, int grid[], int x_blocks, int y_blocks, int block_size, int border_size, int window_width, int window_height) {
int x, y;

SDL_Rect blocks[x_blocks][y_blocks];
for (y = 0; y < y_blocks; ++y) {
for (x = 0; x < x_blocks; ++x) {
blocks[x][y].x = (x * (block_size + border_size)) + border_size;
blocks[x][y].y = (y * (block_size + border_size)) + border_size;
blocks[x][y].w = block_size;
blocks[x][y].h = block_size;
}
}

for (x = 0; x < (x_blocks * y_blocks); ++x) {
if (grid[x] == 1) {
SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF);
SDL_RenderFillRect (renderer, &blocks[x % x_blocks][x / x_blocks]);
}
else if (grid[x] == 0) {
SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderFillRect (renderer, &blocks[x % x_blocks][x / x_blocks]);

}
}
}

我最终通过这个函数 draw_blocks 跟踪了段错误并进入了 SDL_SetRenderDrawColor。这是我的 gdb 输出:

(gdb) run

Starting program: /home/arch/dev/cell/cell

[Thread debugging using libthread_db enabled]

Using host libthread_db library "/usr/lib/libthread_db.so.1".

Xlib: extension "GLX" missing on display ":0.0".



Breakpoint 1, draw_borders (renderer=0xffffffffffffffff, x_blocks=80, y_blocks=80, block_size=8, border_size=1, window_width=721, window_height=721) at ./cell.c:112

112 SDL_SetRenderDrawColor(renderer, 0x7F, 0x7F, 0x7F, 0xFF);

(gdb) step

SDL_SetRenderDrawColor (a=0xffffffffffffffff, b=127 '\177', c=127 '\177', d=127 '\177', e=255 '\377') at /home/arch/downloads/sdl/src/dynapi/SDL_dynapi_procs.h:365

365 SDL_DYNAPI_PROC(int,SDL_SetRenderDrawColor,(SDL_Renderer *a, Uint8 b, Uint8 c, Uint8 d, Uint8 e),(a,b,c,d,e),return)

(gdb) next

SDL_SetRenderDrawColor_REAL (renderer=0xffffffffffffffff, r=127 '\177', g=127 '\177', b=127 '\177', a=255 '\377') at /home/arch/downloads/sdl/src/render/SDL_render.c:1281

1281 {

(gdb) step

1282 CHECK_RENDERER_MAGIC(renderer, -1);

(gdb) step



Program received signal SIGSEGV, Segmentation fault.

0x00007ffff7b0c410 in SDL_SetRenderDrawColor_REAL (renderer=0xffffffffffffffff, r=127 '\177', g=127 '\177', b=127 '\177', a=255 '\377') at /home/arch/downloads/sdl/src/render/SDL_render.c:1282

1282 CHECK_RENDERER_MAGIC(renderer, -1);

(gdb) up

#1 0x00000000004014b6 in draw_borders (renderer=0xffffffffffffffff, x_blocks=80, y_blocks=80, block_size=8, border_size=1, window_width=721, window_height=721) at ./cell.c:112

112 SDL_SetRenderDrawColor(renderer, 0x7F, 0x7F, 0x7F, 0xFF);

(gdb) up

#2 0x0000000000400d19 in main () at ./cell.c:38

38 draw_borders (renderer, x_blocks, y_blocks, block_size, border_size, window_width, window_height);

(gdb) up

Initial frame selected; you cannot go up.

(gdb)

我感觉指针和引用有问题,但我现在对这些没有太多经验。根据我的阅读和思考,我认为使用 renderer = SDL_CreateSoftwareRenderer(surface); 创建的渲染器只是 init_display 函数的本地渲染器,而不是传递给主函数; SDL_SetRenderDrawColor 然后尝试使用不存在的渲染器,但我可能错了。我尝试研究并尝试各种修复,但我要么最终创建了一个 renderer** 参数(SDL_SetRenderDrawColor 需要 renderer*),要么我完全结束了取消引用指针并使其成为 renderer。如何在 main 之外的函数中正确创建渲染器?这甚至是与我的段错误相关的问题吗?

最佳答案

您的问题出在 init_display 函数上。在 C 中,函数参数按值传递,所以当您执行 window = SDL_CreateWindow 时,您实际上更改了函数局部 window 变量,以及您最初传递给此函数的变量值保持不变。

但是,您可以传递指针到指针:

void init_display (SDL_Window **window, SDL_Surface **surface, SDL_Renderer **renderer, int window_width, int window_height) {

SDL_Init(SDL_INIT_VIDEO);

*window = SDL_CreateWindow("Cellular Automaton", 0, 0, window_width, window_height, SDL_WINDOW_SHOWN);
*surface = SDL_GetWindowSurface(*window);
*renderer = SDL_CreateSoftwareRenderer(*surface);

SDL_SetRenderDrawColor(*renderer, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderClear(*renderer);
}

(不是一个好的代码,过多地使用了指针解引用,但这会起作用)

然后当你调用这个函数时:

SDL_Window *window;
SDL_Surface *surface;
SDL_Renderer *renderer;
init_display(&window, &surface, &renderer);

其他代码不需要任何更改。

您还可以将指针传递给具有您需要的所有字段的结构,并从函数中填充该结构。当您有很多字段时,这实际上很常见。

旁注 - 如果您只需要渲染器并且对窗口或表面不感兴趣,为什么不直接将渲染器作为函数的返回值呢?例如。 SDL_Renderer *init_display(int w, int h)

上面代码的稍微好一点的版本会在局部变量中缓存指针,以消除不必要的解引用:

void init_display (SDL_Window **window, SDL_Surface **surface, SDL_Renderer **renderer, int window_width, int window_height) {

SDL_Init(SDL_INIT_VIDEO);

SDL_Window *_window = SDL_CreateWindow("Cellular Automaton", 0, 0, window_width, window_height, SDL_WINDOW_SHOWN);
SDL_Surface *_surface = SDL_GetWindowSurface(_window);
SDL_Renderer *_renderer = SDL_CreateSoftwareRenderer(_surface);

SDL_SetRenderDrawColor(_renderer, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderClear(_renderer);

*window = _window;
*surface = _surface;
*renderer = _renderer;
}

关于c - 在函数内创建渲染器时出现 SDL2 段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31635331/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com