为什么 SDL_Rect* 数组没有按预期运行?

Why is SDL_Rect* array not functioning as intended?

我只是想编写一个程序来使用 SDL 绘制到 window。我正在尝试使用 rects 进行绘制,我想如果我只是不清除屏幕,那么我可以在改变其位置时留下 rect 所在位置的踪迹。然而,这会导致 window 像疯了一样出现故障,所以我想出了另一个解决方案,其中我将在程序绘制时添加一个 Rects 数组,然后每一帧它将通过数组并渲染每个 rect 到正确位置的 window。但是,当尝试从数组中渲染矩形时,它们似乎都在同一位置,而不是在添加到数组之前设置的位置?

#include <SDL2/SDL.h>

#define SCREEN_WIDTH 1920
#define SCREEN_HEIGHT 1080

SDL_Rect *rects[200] = {};

int get_rect_count()
{
    int i;
    for (i = 0; i < sizeof(rects) / sizeof(rects[0]); i++)
    {
        if (rects[i] == NULL)
            break;
    }
    return i;
}

void draw_rects(SDL_Renderer *renderer)
{
    SDL_SetRenderDrawColor(renderer, 0, 255, 255, 255);
    SDL_RenderClear(renderer);
    SDL_SetRenderDrawColor(renderer, 241, 194, 125, 255);
    for (int i = 0; i < get_rect_count(); i++)
    {
        SDL_RenderDrawRect(renderer, rects[i]);
        SDL_RenderFillRect(renderer, rects[i]);
    }
    SDL_RenderPresent(renderer);
}

void ball(int sp_x, int sp_y, SDL_Renderer *renderer)
{
    for (int i = 0; i < 3; i++)
    {
        SDL_Rect rect;
        int offset = i * 10;
        rect.x = sp_x + offset;
        rect.y = sp_y - offset;
        rect.w = 10;
        rect.h = 10;
        rects[i] = &rect;
        draw_rects(renderer);
        SDL_Delay(200);
    }
}

int main(int argc, char *args[])
{
    SDL_Window *window = NULL;
    SDL_Renderer *renderer = NULL;

    if (SDL_Init(SDL_INIT_VIDEO) < 0)
        printf("sdl failed lol");
    else
    {
        window = SDL_CreateWindow("window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, 0);
        renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
        SDL_SetRenderDrawColor(renderer, 0, 255, 255, 255);
        SDL_RenderClear(renderer);
        SDL_RenderPresent(renderer);
        SDL_Delay(750);
        ball(SCREEN_WIDTH / 8, SCREEN_HEIGHT * 0.75, renderer);
        SDL_Delay(1000);
    }
    return 0;
}

这里有一个主要问题:

for (int i = 0; i < 3; i++)
{
    SDL_Rect rect;

这里变量rect在循环内是local。一旦循环迭代,rect的life-time结束,不复存在。您保存的任何指向它的指针都将变得无效,取消引用这些指针将导致 未定义的行为

这就是理论。现实中可能发生的情况是,编译器将重用 rect 的内存,这意味着所有指针都将指向一个 SDL_Rect 结构,您将在循环中的每次迭代中覆盖该结构。所以你最终将所有矩形都设置为最后一个矩形的值。

解决您的问题的一种可能方法是使用 malloc 动态分配矩形。你当然要记得在完成后 free 他们。

另一种解决方案是使用 SDL_Rect 结构对象数组,而不是指针,并使用另一个变量跟踪其“大小”(使用的元素数)。