SDL_BlitSurface 抛出分段错误
SDL_BlitSurface is throwing segmentation fault error
我正在尝试使用菜单 class 显示菜单。但是在 class 的函数 draw()
中,SDL_BlitSurface
不工作并且在执行此行时抛出分段默认值:
SDL_BlitSurface(el.surfaceNormal, NULL, surface, &el.rect);
函数代码如下:
void Menu::draw(SDL_Surface* surface) {
for(int i=0; i<menuElementList.size(); i++){
auto el = menuElementList.at(i);
SDL_BlitSurface(el.surfaceNormal, NULL, surface, &el.rect);
}
}
我在向量中使用的结构:
struct menuElement{
SDL_Surface* surfaceNormal;
SDL_Surface* surfaceHover;
SDL_Rect rect;
std::string text;
};
通常情况下,我应该能够渲染矢量中存在的所有表面,但由于我无法理解的原因,它不起作用。
填充向量的代码:
void Menu::addMenu(std::string name, int x, int y) {
menuElement m;
TTF_Font* Sans = TTF_OpenFont("OpenSans-Light.ttf", 25);
if(!Sans){
std::cout << TTF_GetError() << std::endl;
}
SDL_Color White = {255, 255, 255};
SDL_Surface* surfaceMessage = TTF_RenderText_Solid(Sans, name.c_str(), White);
m.surfaceNormal = surfaceMessage;
SDL_Color Red = {255, 0, 0};
SDL_Surface* hoverMessage = TTF_RenderText_Solid(Sans, name.c_str(), Red);
m.surfaceHover = hoverMessage;
SDL_Rect rect;
rect.x = rect.y = 50;
m.rect = rect;
m.text = name;
SDL_FreeSurface(surfaceMessage);
SDL_FreeSurface(hoverMessage);
menuElementList.push_back(m);
}
我知道矢量会被填充,因为我可以显示其中每个元素的文本属性。怎么了?
好吧,这个错误非常简单,如果稍微调试一下你就会意识到,这是你应该完成的 MVCE。
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include <iostream>
#include <vector>
#include <string>
#define HEIGHT 600
#define WIDTH 800
using namespace std;
struct menuElement{
SDL_Surface* surfaceNormal;
SDL_Surface* surfaceHover;
SDL_Rect rect;
std::string text;
};
std::vector<menuElement> menuElementList;
void add_element(std::string name, int x, int y) {
menuElement m;
TTF_Font* Sans = TTF_OpenFont("OpenSans-Light.ttf", 25);
if(!Sans){
std::cout << TTF_GetError() << std::endl;
}
SDL_Color White = {255, 255, 255};
SDL_Surface* surfaceMessage = TTF_RenderText_Solid(Sans, name.c_str(), White);
m.surfaceNormal = surfaceMessage;
SDL_Color Red = {255, 0, 0};
SDL_Surface* hoverMessage = TTF_RenderText_Solid(Sans, name.c_str(), Red);
m.surfaceHover = hoverMessage;
SDL_Rect rect{x, y, 50, 50}; // You were never using x and y before now it draws at that position with a rect of size 50x50
m.rect = rect;
m.text = name;
// SDL_FreeSurface(surfaceMessage); << how is this not crashing in your system when blitting, I don't know
// SDL_FreeSurface(hoverMessage);
menuElementList.push_back(m);
}
int main() {
SDL_Init(SDL_INIT_VIDEO);
TTF_Init();
SDL_Window *window = SDL_CreateWindow("TextFail", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_SHOWN);
SDL_Surface *surface = SDL_GetWindowSurface(window);
bool quit = false;
SDL_Event event;
add_element("ello", 20, 20);
add_element("Bye", 40, 40);
while (!quit) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
quit = true;
}
}
for (auto &el : menuElementList)
SDL_BlitSurface(el.surfaceNormal, NULL, surface, &el.rect);
SDL_UpdateWindowSurface(window);
}
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
我评论了让你感到困惑的 2 行,即使矢量被填充它也被未初始化的数据填充,因为你释放了表面,你应该在释放 menuElement 时这样做(如果你在例如 menuElement 析构函数或 free_menu_element(menuElement *e) { .. } 函数 if C)
请记住,当您复制指针时,您复制的是它们指向的内存方向,而不是其内容。
您也从未使用过 x 和 y!
我正在尝试使用菜单 class 显示菜单。但是在 class 的函数 draw()
中,SDL_BlitSurface
不工作并且在执行此行时抛出分段默认值:
SDL_BlitSurface(el.surfaceNormal, NULL, surface, &el.rect);
函数代码如下:
void Menu::draw(SDL_Surface* surface) {
for(int i=0; i<menuElementList.size(); i++){
auto el = menuElementList.at(i);
SDL_BlitSurface(el.surfaceNormal, NULL, surface, &el.rect);
}
}
我在向量中使用的结构:
struct menuElement{
SDL_Surface* surfaceNormal;
SDL_Surface* surfaceHover;
SDL_Rect rect;
std::string text;
};
通常情况下,我应该能够渲染矢量中存在的所有表面,但由于我无法理解的原因,它不起作用。
填充向量的代码:
void Menu::addMenu(std::string name, int x, int y) {
menuElement m;
TTF_Font* Sans = TTF_OpenFont("OpenSans-Light.ttf", 25);
if(!Sans){
std::cout << TTF_GetError() << std::endl;
}
SDL_Color White = {255, 255, 255};
SDL_Surface* surfaceMessage = TTF_RenderText_Solid(Sans, name.c_str(), White);
m.surfaceNormal = surfaceMessage;
SDL_Color Red = {255, 0, 0};
SDL_Surface* hoverMessage = TTF_RenderText_Solid(Sans, name.c_str(), Red);
m.surfaceHover = hoverMessage;
SDL_Rect rect;
rect.x = rect.y = 50;
m.rect = rect;
m.text = name;
SDL_FreeSurface(surfaceMessage);
SDL_FreeSurface(hoverMessage);
menuElementList.push_back(m);
}
我知道矢量会被填充,因为我可以显示其中每个元素的文本属性。怎么了?
好吧,这个错误非常简单,如果稍微调试一下你就会意识到,这是你应该完成的 MVCE。
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include <iostream>
#include <vector>
#include <string>
#define HEIGHT 600
#define WIDTH 800
using namespace std;
struct menuElement{
SDL_Surface* surfaceNormal;
SDL_Surface* surfaceHover;
SDL_Rect rect;
std::string text;
};
std::vector<menuElement> menuElementList;
void add_element(std::string name, int x, int y) {
menuElement m;
TTF_Font* Sans = TTF_OpenFont("OpenSans-Light.ttf", 25);
if(!Sans){
std::cout << TTF_GetError() << std::endl;
}
SDL_Color White = {255, 255, 255};
SDL_Surface* surfaceMessage = TTF_RenderText_Solid(Sans, name.c_str(), White);
m.surfaceNormal = surfaceMessage;
SDL_Color Red = {255, 0, 0};
SDL_Surface* hoverMessage = TTF_RenderText_Solid(Sans, name.c_str(), Red);
m.surfaceHover = hoverMessage;
SDL_Rect rect{x, y, 50, 50}; // You were never using x and y before now it draws at that position with a rect of size 50x50
m.rect = rect;
m.text = name;
// SDL_FreeSurface(surfaceMessage); << how is this not crashing in your system when blitting, I don't know
// SDL_FreeSurface(hoverMessage);
menuElementList.push_back(m);
}
int main() {
SDL_Init(SDL_INIT_VIDEO);
TTF_Init();
SDL_Window *window = SDL_CreateWindow("TextFail", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_SHOWN);
SDL_Surface *surface = SDL_GetWindowSurface(window);
bool quit = false;
SDL_Event event;
add_element("ello", 20, 20);
add_element("Bye", 40, 40);
while (!quit) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
quit = true;
}
}
for (auto &el : menuElementList)
SDL_BlitSurface(el.surfaceNormal, NULL, surface, &el.rect);
SDL_UpdateWindowSurface(window);
}
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
我评论了让你感到困惑的 2 行,即使矢量被填充它也被未初始化的数据填充,因为你释放了表面,你应该在释放 menuElement 时这样做(如果你在例如 menuElement 析构函数或 free_menu_element(menuElement *e) { .. } 函数 if C)
请记住,当您复制指针时,您复制的是它们指向的内存方向,而不是其内容。
您也从未使用过 x 和 y!