2015-04-17 66 views
0

我正在使用SDL創建測驗遊戲程序。代碼編譯得很好,但是當我運行輸出可執行文件時,出現了分段錯誤。我正試圖將一個按鈕閃爍到屏幕上。這裏是我的代碼:C++ Debian 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; 
} 

th ablit功能用於blitting,而abutton功能用於創建按鈕圖像。

+0

嘗試使用調試器來了解SegFault何時發生,以及如果仍然無法解決問題,請在此處輸出調試器的輸出。另一件事是,你永遠不會檢查函數的返回值,所以如果某些表面或字體爲空,則不能被警告。 – Lovy

回答

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會在編譯時告訴你未初始化的指針(我建議給你的g++標誌加上-Wall -Wextra -pedantic)。
  2. 學習使用調試器(GDB是一個優秀的)。會告訴你一切。
  3. 試試記憶清潔劑(編號爲-fsanitize=address -g)。它會很好地告訴你,出了什麼問題。