C ++ Debian SDL分段错误

时间:2015-04-17 16:25:23

标签: c++ segmentation-fault g++ debian sdl

我正在使用SDL创建一个问答游戏程序。代码编译得很好,但是当我运行输出可执行文件时,我遇到了分段错误。我试图在屏幕上按一下按钮。这是我的代码:

#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include <stdio.h>
#undef main

void ablit(SDL_Surface* source, SDL_Surface* destination, int x, int y){
        SDL_Rect offset;
        offset.x = x;
        offset.y = y;
        SDL_BlitSurface(source, NULL, destination, &offset);
}

void acreatebutton(int x, int y, int w, int h, SDL_Color fill, SDL_Surface*                    
screenSurface, const char* buttontext, int fontsize, SDL_Color textfill){
        SDL_Rect* buttonrect;
        buttonrect->x = x;
        buttonrect->y = y;
        buttonrect->w = w;
        buttonrect->h = h;
        int fillint = SDL_MapRGB(screenSurface -> format, fill.r, fill.g, 
fill.b);
    SDL_FillRect(screenSurface, buttonrect, fillint);
    TTF_Font* font = TTF_OpenFont("/usr/share/fonts/truetype/droid/DroidSansMono.ttf", fontsize);
    SDL_Surface* buttontextsurface = TTF_RenderText_Solid(font, buttontext, textfill);
    ablit(buttontextsurface, screenSurface, 300, 300);
    TTF_CloseFont(font);
}

int main(int argc, char** argv){
        SDL_Init(SDL_INIT_EVERYTHING);
        TTF_Init();
        SDL_Window* screen = SDL_CreateWindow("Quiz Game",   SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 500, 400,SDL_WINDOW_RESIZABLE);
    SDL_Surface* screenSurface = SDL_GetWindowSurface( screen );
    SDL_FillRect (screenSurface, NULL, SDL_MapRGB( screenSurface->format, 0, 0, 255 ) );
    SDL_Color black = {0, 0, 0};
    TTF_Font* afont = TTF_OpenFont("/usr/share/fonts/truetype/droid/DroidSansMono.ttf", 35);
    SDL_Surface* aQuiz_Game = TTF_RenderText_Solid(afont, "Quiz Game", black);
    ablit(aQuiz_Game, screenSurface, 150, 50);
    acreatebutton(175, 350, 200, 50, black, screenSurface, "Take Quiz", 35, black);
    SDL_UpdateWindowSurface( screen );
    SDL_Event windowEvent;
    while (true){
        if (SDL_PollEvent(&windowEvent))
        {
            if (windowEvent.type == SDL_KEYUP &&
            windowEvent.key.keysym.sym == SDLK_ESCAPE) break;
        }
        SDL_GL_SwapWindow(screen);
    }
    TTF_CloseFont(afont);
    SDL_Quit();
    TTF_Quit();
    return 0;
}

ablit功能用于blitting,而abutton功能用于创建按钮图像。

1 个答案:

答案 0 :(得分:2)

你应该表明,你的代码在哪里获得了段错误,否则很难猜到。

首先罪魁祸首可能就是这条线:

TTF_Font* afont = TTF_OpenFont("/usr/share/fonts/truetype/droid/DroidSansMono.ttf", 35);

您可以创建字体,但不会检查字体是否成功。如果您的计算机上不存在字体文件,则可能会出现分段错误。

第二个问题出在函数acreatebutton中。您将buttonrect声明为指针,但从不初始化它!它是一个UB,可能会做任何事情,例如崩溃你的程序。 在这种情况下,您可能根本不需要它作为指针,因此将其更改为堆栈上的简单变量应该有效:

SDL_Rect buttonrect;
buttonrect.x = x;
/* more code ... */
SDL_FillRect(screenSurface, &buttonrect, fillint);

您可以非常轻松地找到这两个问题。

  1. 启用所有警告。 GCC会在编译时告诉您有关未初始化的指针(我建议将-Wall -Wextra -pedantic添加到g++标志中)。
  2. 学习使用调试器(GDB是一个非常好的调试器)。会告诉你一切。
  3. 尝试使用内存清理程序(使用-fsanitize=address -g编译)。它会很好地告诉你,出了什么问题。