You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SDL2中SDL_Delay()触发SDL_QUIT退出时程序冻结的修复方法

问题根因
  • 在SDL_QUIT事件处理分支中提前调用了SDL_Quit()销毁了所有SDL运行资源,但此时主循环并未结束,后续执行的SDL_RenderPresent()、SDL_Delay()等API依赖已销毁的SDL环境,触发未定义行为导致窗口冻结。
  • 单次调用SDL_PollEvent()每次循环仅能处理事件队列中的第一个事件,存在事件遗漏风险。
  • 当帧处理耗时超过16.666ms时,floor(16.666f - elapsedMS)会返回负数,SDL_Delay()传入负数参数会产生异常。
修复方案
  1. 移除SDL_QUIT分支中的SDL_Quit()调用,仅修改running变量标记循环结束,在主循环退出后统一执行资源销毁和SDL_Quit()调用。
  2. 用while循环包裹SDL_PollEvent(),确保事件队列中所有待处理事件都被消费完毕。
  3. 对SDL_Delay的输入参数做边界校验,仅当计算得到的延时值大于0时才执行延时,避免传入非法参数。
修复后完整代码
#include <SDL2/SDL.h>
#include <math.h>

const int WINDOW_WIDTH = 1000;
const int WINDOW_HEIGHT = 750;

int main(int argc, char *args[]) {

    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: %s", SDL_GetError());
        return 1;
    }
    SDL_Window *window;
    SDL_Renderer *renderer;
    SDL_Event e;

    bool running = true;

    if (SDL_CreateWindowAndRenderer(WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: %s", SDL_GetError());
        return 1;
    }

    while (running) {
        Uint64 start = SDL_GetPerformanceCounter();
        
        // 循环处理所有待处理事件
        while (SDL_PollEvent(&e)) {
            switch (e.type) {
                case SDL_QUIT:
                    running = false;
                    break;
            }
        }
        
        SDL_RenderPresent(renderer);

        Uint64 end = SDL_GetPerformanceCounter();
        float elapsedMS = (end - start) / (float) SDL_GetPerformanceFrequency() * 1000.0f;
        int delayMS = (int)floor(16.666f - elapsedMS);
        // 仅当延时值合法时执行延时
        if (delayMS > 0) {
            SDL_Delay(delayMS);
        }
    }

    // 统一销毁资源后退出
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}

内容的提问来源于stack exchange,提问作者Magikarpm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 08:27:04