【问题标题】:SDL crashes when any standard variable is declared声明任何标准变量时 SDL 崩溃
【发布时间】:2013-12-20 07:24:07
【问题描述】:

此 SDL 程序运行良好(显示一个窗口并在其上绘制位图),但是,如果我在程序中声明任何变量(例如 int、long 等),窗口将冻结并变为白色而不是黑色什么都没有。什么可能导致这种情况?

#include <stdio.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>

int main(int argc, char* argv[]) {
    // line below will cause SDL crash
    // int blabla = 640; 
    SDL_Window *window;
    SDL_Init(SDL_INIT_VIDEO);
    window = SDL_CreateWindow(
        "A rather exceptional SDL window",
        SDL_WINDOWPOS_UNDEFINED,
        SDL_WINDOWPOS_UNDEFINED,
        640,
        480,
        SDL_WINDOW_OPENGL
    );
    if (window == NULL) {
        printf("Could not create window: %s\n", SDL_GetError());
        return 1;
    }
    SDL_Renderer *renderer;
    SDL_Texture *texture;
    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
    SDL_Surface *brush;
    brush = IMG_Load("brush2.png");
    texture = SDL_CreateTextureFromSurface(renderer, brush);
    SDL_RenderClear(renderer);
    SDL_Rect *sRect, *dRect;
    sRect->w = 10;
    sRect->h = 4;
    sRect->x = 0;
    sRect->y = 0;
    dRect->w = 10;
    dRect->h = 4;
    dRect->x = 10;
    dRect->y = 10;
    SDL_RenderCopy(renderer, texture, sRect, dRect);
    SDL_RenderPresent(renderer);
    SDL_Delay(1000);
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}

【问题讨论】:

  • 你在哪里声明了那个变量?
  • @rullof 查看注释掉的行“int blabla = 640” - 是的,确实,如果声明了不相关的变量(或任何不相关的变量),SDL 将冻结并不画。如果没有 SDL 代码,它将可以正常编译并且不会出现任何问题,但由于某种原因,如果我尝试定义任何不相关的标准变量(例如注释掉的行),SDL 会冻结。
  • 换句话说,由于“int blabla = 640”被注释掉了,所以你在上面看到的代码编译得很好。如果你取消注释 "int blabla = 640" 或写 "int bob = 44" 或 "long joe = 34",它当然会编译得很好,但 SDL 会冻结 而不会绘制。我希望这是有道理的。

标签: c crash sdl sdl-2


【解决方案1】:

您正在写入未分配的内存。

SDL_Rect *sRect, *dRect;
sRect->w = 10; /* w doesn't exist. Writing is undefined behaviour. */

sRectdRect 只是指针。在访问结构成员之前,它们需要指向有效内存。

您可以改为在堆栈中声明它们:

SDL_Rect sRect, dRect;
sRect.w = 10;
sRect.h = 4;
...
SDL_RenderCopy(renderer, texture, &sRect, &dRect);

您还应该检查SDL_-functions 的返回值。如果这些都失败了,而您仍然继续执行,您可能会遇到奇怪的行为或崩溃。

【讨论】:

  • 这些行不会导致错误 - SDL 要求提供指针并且该代码有效。它只是声明一个导致 SDL 冻结的变量(任何变量,与 SDL 无关 -- unrelated 是关键部分)。请参阅注释掉的行“int blabla = 640” 如果我取消注释该行或声明任何变量,SDL 将冻结。如果我 not 声明任何变量,一切正常,SDL 会在屏幕上绘制。一个可能与另一个有什么关系? “blabla”变量甚至没有在程序中使用,也不会导致任何错误 - 为什么在声明不相关的变量时 SDL 会冻结?
  • sRect-&gt;w = 10; 写入未分配区域。这将导致未定义的行为。这意味着任何事情都可能发生。它可能工作,它可能不工作,它可能由于完全不相关的原因而崩溃。声明变量blabla 很可能会改变sRect 在堆栈上的位置,这意味着指针的初始(垃圾)值不同。它的工作首先是纯粹的运气。
  • 谢谢 - 您的解决方案确实解决了它。我仍然不明白为什么 C 会让你写到未分配的区域(那么分配的意义何在?)以及这意味着“任何事情都可能发生”(例如,即使未分配的区域是“blabla”var,它仍然应该'不影响 SDL,因为该变量永远不会被 SDL 或在那之后的任何东西访问。但它可以工作,所以再次感谢,我会继续前进。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-03
  • 2013-09-25
相关资源
最近更新 更多