使用SDL_CreateWindow遇操作数错误及指针警告,窗口闪崩
原始错误代码
#include <stdio.h> #define SDL_MAIN_HANDLED #include <SDL2/SDL.h> #include <SDL2/SDL_events.h> #include <SDL2/SDL_video.h> int main() { int SDL_Window; SDL_Window * SDL_CreateWindow("title", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 720, 480, 0); }
第一个编译错误
main.c: In function 'main':
main.c:9:20: error: invalid operands to binary * (have 'int' and 'SDL_Window *')
9 | SDL_Window * SDL_CreateWindow("title", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 720, 480, 0);
| ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| |
| SDL_Window *
错误原因:
- 混淆了类型和变量:
SDL_Window是SDL官方定义的窗口结构体类型,你却把它当成自定义变量名,还错误定义为int类型。 - 第二行写法会被编译器解析为「用int变量
SDL_Window乘以SDL_CreateWindow的返回值」,属于非法语法。
第二个编译警告
改成SDL_Window = SDL_CreateWindow("title", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 720, 480, 0);后,错误消失但出现警告:
main.c: In function 'main':
main.c:9:20: warning: assignment to 'int' from 'SDL_Window *' makes integer from pointer without a cast [-Wint-conversion]
9 | SDL_Window = SDL_CreateWindow("title", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 720, 480, 0);
| ^
警告原因:SDL_CreateWindow返回的是指向SDL_Window结构体的指针,你却把它赋值给int变量。指针和int的内存长度、语义完全不同,这种类型不匹配会导致后续操作(比如销毁窗口)出现内存错误。
窗口崩溃的原因
运行时窗口弹出即崩溃,核心原因有两个:
- 变量类型错误导致SDL无法正确识别窗口句柄;
- 代码缺少SDL初始化和事件循环:SDL程序必须先初始化对应子系统,还要通过事件循环维持窗口运行,main函数直接结束会导致SDL资源被强制回收,引发崩溃。
正确的完整代码示例
#include <stdio.h> #define SDL_MAIN_HANDLED #include <SDL2/SDL.h> int main() { // 初始化SDL视频子系统 if (SDL_Init(SDL_INIT_VIDEO) != 0) { printf("SDL初始化失败: %s\n", SDL_GetError()); return 1; } // 正确定义窗口指针变量,存储CreateWindow的返回值 SDL_Window* window = SDL_CreateWindow( "title", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 720, 480, 0 ); if (!window) { printf("窗口创建失败: %s\n", SDL_GetError()); SDL_Quit(); return 1; } // 事件循环,维持窗口运行 SDL_Event event; int running = 1; while (running) { // 处理窗口事件(比如关闭窗口) while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) { running = 0; } } } // 销毁窗口资源 SDL_DestroyWindow(window); // 退出SDL,释放所有资源 SDL_Quit(); return 0; }
关键注意事项
- 不要用
int存储SDL对象指针,必须使用SDL定义的对应指针类型(如SDL_Window*); - SDL程序启动前必须调用
SDL_Init初始化所需子系统(这里是视频子系统SDL_INIT_VIDEO); - 必须通过事件循环维持程序运行,否则窗口会立即关闭;
- 程序结束前要销毁创建的SDL资源,再调用
SDL_Quit释放所有SDL资源。
内容的提问来源于stack exchange,提问作者Minignoux

