C++ Debian SDL 分段错误
C++ Debian SDL segmentation fault
我正在使用 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 函数用于创建按钮图像。
你应该说明,你的代码是在哪里出现段错误的,否则很难猜到。
第一个 罪魁祸首可能是:
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);
你可以很容易地找到这两个问题。
- 启用所有警告。 GCC 会在编译时告诉你未初始化的指针(我建议添加
-Wall -Wextra -pedantic
给你 g++
标志)。
- 学习使用调试器(
GDB
是一个很好的调试器)。会告诉你一切。
- 尝试内存清理器(使用
-fsanitize=address -g
编译)。它会很好地告诉你哪里出了问题。
我正在使用 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 函数用于创建按钮图像。
你应该说明,你的代码是在哪里出现段错误的,否则很难猜到。
第一个 罪魁祸首可能是:
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);
你可以很容易地找到这两个问题。
- 启用所有警告。 GCC 会在编译时告诉你未初始化的指针(我建议添加
-Wall -Wextra -pedantic
给你g++
标志)。 - 学习使用调试器(
GDB
是一个很好的调试器)。会告诉你一切。 - 尝试内存清理器(使用
-fsanitize=address -g
编译)。它会很好地告诉你哪里出了问题。