使用 sf::Text 的数组时崩溃
Crash when using arrays of sf::Text
当我加载和设置字体时,应用程序崩溃并且调试器在 MainMenu.cpp 中的行显示 0xc0000005(异常由 sfml-graphics-d-2.dll 报告):
window.draw(menu.at[i]);
这是 for 循环中的行。
顺便说一句。每次我关闭我的应用程序时都会出现错误 "Run-Time Check Failure #2 - Stack around the variable 'window' was corrupted." 并且调试器显示 main().
结束
MainMenu.h:
#include <SFML/Graphics.hpp>
class MainMenu
{
public:
MainMenu();
void draw(sf::RenderWindow& window);
void MoveUp();
void MoveDown();
private:
std::array<sf::Text,3> menu;
sf::Font arial;
unsigned int cursor{ 0 };
};
MainMenu.cpp:
#include "MainMenu.h"
#include <SFML/Graphics.hpp>
#include <iostream>
constexpr int PLAY{ 1 };
constexpr int SETTINGS{ 2 };
constexpr int EXIT{ 3 };
MainMenu::MainMenu()
{
arial.loadFromFile("ArialUnicodeMS.ttf");
menu[0].setFont(arial);
menu[0].setCharacterSize(40);
menu[0].setFillColor(sf::Color::White);
menu[0].setString("Play!");
menu[0].setPosition(sf::Vector2f(400, PLAY * 40));
menu[1].setFont(arial);
menu[1].setCharacterSize(40);
menu[1].setFillColor(sf::Color::White);
menu[1].setString("Settings");
menu[1].setPosition(sf::Vector2f(400, SETTINGS * 40));
menu[2].setFont(arial);
menu[2].setCharacterSize(40);
menu[2].setFillColor(sf::Color::White);
menu[2].setString("Exit");
menu[2].setPosition(sf::Vector2f(400, EXIT * 40));
}
void MainMenu::draw(sf::RenderWindow& window)
{
for (int i = 0; i < 3; i++)
{
window.draw(menu[i]);
}
}
void MainMenu::MoveUp()
{
if (cursor - 1 >= 0)
{
std::cout << "moved up!";
menu[cursor].setFillColor(sf::Color::White);
cursor--;
menu[cursor].setFillColor(sf::Color::Red);
}
}
void MainMenu::MoveDown()
{
if (cursor + 1 < 3)
{
std::cout << "moved down!";
menu[cursor].setFillColor(sf::Color::White);
cursor++;
menu[cursor].setFillColor(sf::Color::Red);
}
}
main.cpp:
#include "Game.h"
#include "MainMenu.h"
#include "ConstState.h"
#include "Settings.h"
#include <SFML/Graphics.hpp>
#include <iostream>
int main()
{
sf::RenderWindow window(sf::VideoMode(800,600), "test");
Game game;
MainMenu menu;
Settings settings;
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
switch (event.type)
{
case sf::Event::KeyReleased:
switch (event.key.code)
{
case sf::Keyboard::Up:
menu.moveUp();
break;
case sf::Keyboard::Down:
menu.moveDown();
break;
case sf::Keyboard::Return:
switch (menu.getCursor())
{
case 0:
std::cout << "play";
game.run(window);
break;
case 1:
std::cout << "settings";
break;
case 2:
window.close();
break;
}
break;
}
break;
case sf::Event::Closed:
window.close();
break;
}
}
window.clear(sf::Color::Red);
menu.draw(window);
window.display();
}
return 0;
}
在 MainMenu::MoveUp()
你写:if (cursor - 1 >= 0) ...
首先,这个条件总是true
:cursor
是一个unsigned int
,所以它没有其他选择,只能是>= 0
.
其次,在 cursor
为 0
的情况下,您的 cursor - 1
会产生 unsigned int 的最大值(因为它在溢出时回绕)。结果,menu[cursor].setFillColor...
导致未定义的行为,因为您给 std::array<sf::Text, 3> menu
一个无效索引。
尝试修复此问题并检查错误是否再次出现。
当我加载和设置字体时,应用程序崩溃并且调试器在 MainMenu.cpp 中的行显示 0xc0000005(异常由 sfml-graphics-d-2.dll 报告):
window.draw(menu.at[i]);
这是 for 循环中的行。
顺便说一句。每次我关闭我的应用程序时都会出现错误 "Run-Time Check Failure #2 - Stack around the variable 'window' was corrupted." 并且调试器显示 main().
结束MainMenu.h:
#include <SFML/Graphics.hpp>
class MainMenu
{
public:
MainMenu();
void draw(sf::RenderWindow& window);
void MoveUp();
void MoveDown();
private:
std::array<sf::Text,3> menu;
sf::Font arial;
unsigned int cursor{ 0 };
};
MainMenu.cpp:
#include "MainMenu.h"
#include <SFML/Graphics.hpp>
#include <iostream>
constexpr int PLAY{ 1 };
constexpr int SETTINGS{ 2 };
constexpr int EXIT{ 3 };
MainMenu::MainMenu()
{
arial.loadFromFile("ArialUnicodeMS.ttf");
menu[0].setFont(arial);
menu[0].setCharacterSize(40);
menu[0].setFillColor(sf::Color::White);
menu[0].setString("Play!");
menu[0].setPosition(sf::Vector2f(400, PLAY * 40));
menu[1].setFont(arial);
menu[1].setCharacterSize(40);
menu[1].setFillColor(sf::Color::White);
menu[1].setString("Settings");
menu[1].setPosition(sf::Vector2f(400, SETTINGS * 40));
menu[2].setFont(arial);
menu[2].setCharacterSize(40);
menu[2].setFillColor(sf::Color::White);
menu[2].setString("Exit");
menu[2].setPosition(sf::Vector2f(400, EXIT * 40));
}
void MainMenu::draw(sf::RenderWindow& window)
{
for (int i = 0; i < 3; i++)
{
window.draw(menu[i]);
}
}
void MainMenu::MoveUp()
{
if (cursor - 1 >= 0)
{
std::cout << "moved up!";
menu[cursor].setFillColor(sf::Color::White);
cursor--;
menu[cursor].setFillColor(sf::Color::Red);
}
}
void MainMenu::MoveDown()
{
if (cursor + 1 < 3)
{
std::cout << "moved down!";
menu[cursor].setFillColor(sf::Color::White);
cursor++;
menu[cursor].setFillColor(sf::Color::Red);
}
}
main.cpp:
#include "Game.h"
#include "MainMenu.h"
#include "ConstState.h"
#include "Settings.h"
#include <SFML/Graphics.hpp>
#include <iostream>
int main()
{
sf::RenderWindow window(sf::VideoMode(800,600), "test");
Game game;
MainMenu menu;
Settings settings;
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
switch (event.type)
{
case sf::Event::KeyReleased:
switch (event.key.code)
{
case sf::Keyboard::Up:
menu.moveUp();
break;
case sf::Keyboard::Down:
menu.moveDown();
break;
case sf::Keyboard::Return:
switch (menu.getCursor())
{
case 0:
std::cout << "play";
game.run(window);
break;
case 1:
std::cout << "settings";
break;
case 2:
window.close();
break;
}
break;
}
break;
case sf::Event::Closed:
window.close();
break;
}
}
window.clear(sf::Color::Red);
menu.draw(window);
window.display();
}
return 0;
}
在 MainMenu::MoveUp()
你写:if (cursor - 1 >= 0) ...
首先,这个条件总是true
:cursor
是一个unsigned int
,所以它没有其他选择,只能是>= 0
.
其次,在 cursor
为 0
的情况下,您的 cursor - 1
会产生 unsigned int 的最大值(因为它在溢出时回绕)。结果,menu[cursor].setFillColor...
导致未定义的行为,因为您给 std::array<sf::Text, 3> menu
一个无效索引。
尝试修复此问题并检查错误是否再次出现。