【问题标题】:Strange segfault from SDL_FreeSurface来自 SDL_FreeSurface 的奇怪段错误
【发布时间】:2016-11-08 20:33:08
【问题描述】:

我有以下简单的 SDL 代码:

#include <SDL.h>
#include <stdbool.h>
#include <stdio.h>

// helpers

bool init(SDL_Window **win, SDL_Surface **surf) {
        int const width = 800;
        int const height = 600;
        if (SDL_Init(SDL_INIT_VIDEO) != 0) {
                fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
                return false;
        }
        *win = SDL_CreateWindow("Picture test",
                                SDL_WINDOWPOS_CENTERED,
                                SDL_WINDOWPOS_CENTERED,
                                width, height, 0);
        if (*win == NULL) {
                fprintf(stderr,
                        "Unable to create window: %s\n",
                        SDL_GetError());
                return false;
        }
        *surf = SDL_GetWindowSurface(*win);
        return true;
}

bool load_media(SDL_Surface **surf) {
        *surf = SDL_LoadBMP("./sample.bmp");
        if (*surf == NULL) {
                fprintf(stderr, "Unable to load data: %s\n", SDL_GetError());
                return false;
        }
        return true;
}

void close(SDL_Window **win, SDL_Surface **surf) {
        SDL_FreeSurface(*surf);
        SDL_DestroyWindow(*win);
        SDL_Quit();
}


int main()
{
        SDL_Window *win;
        SDL_Surface *surf;
        SDL_Surface *img;
        if (!init(&win, &surf)) {
                return EXIT_FAILURE;
        }
        if (!load_media(&img)) {
                return EXIT_FAILURE;
        }
        SDL_BlitSurface(img, NULL, surf, NULL);
        SDL_UpdateWindowSurface(win);
        SDL_Delay(2000);
        close(&win, &img);
}

我的代码总是在close 上出现段错误(根据 GDB,段错误的起源是 SDL_FreeSurface(*surf) 行)。更奇怪的是,如果我用它的定义替换对close 的调用,这仍然会在完全相同的位置出现段错误。具体来说,如果我将close(&amp;win, &amp;img) 替换为:

SDL_FreeSurface(img);
SDL_DestroyWindow(win);
SDL_Quit();

代码仍然在完全相同的位置出现段错误,即使该函数甚至没有被调用。只有当我删除整个 close 函数时,它才能正常工作。我完全不知道是什么原因造成的。

【问题讨论】:

  • 你知道有一个C库函数int close(int fd);吗?是否有任何冲突 - 编译器警告?
  • @WeatherVane 我尝试将 close 重命名为其他名称,然后修复了它!令人惊讶的是,尽管有所有可以想象的警告,编译器仍然接受它!
  • @KozRoss 此外,它可能会在没有任何警告的情况下被接受,因为在 glibc 中 close (和许多其他人)是一个弱符号。使用这种简单的名称(和有限的范围),使用 static 函数可能是合理的。

标签: c segmentation-fault sdl


【解决方案1】:

请重命名你的函数

void close(SDL_Window **win, SDL_Surface **surf)

因为close 是标准C 库函数。

【讨论】:

    【解决方案2】:

    我可以确认这一点。同样的场景。即使使用-Wall-Wextra,编译器也没有发出重新声明警告。 open() 也一样。

    如果这是 gcc 错误,我需要专家的意见。

    • 解决方案 1:将您的 close() 声明为静态函数(例如 static close())。
    • 解决方案 2:将您的 close() 函数重命名为其他名称(例如 my_close_foo())。

    【讨论】:

    • 希望这是一个错误 - 如果 GCC 至少没有警告你这显然是愚蠢的事情,那将是相当可怕的。 Clang 也是如此。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多