编译后出现异常 0x00000004 (sfml-graphics-2.dll)
Exception 0x00000004 (sfml-graphics-2.dll) occuring after compilation
最近开始学习SFML。我想做的第一件事是一个简单的菜单 - 所以我为所有菜单创建了一个界面,包含受保护字段中其他菜单所需的一切。但是,我的代码有时会抛出异常,我不知道为什么。
#include <SFML/Graphics.hpp>
#include <iostream>
class Menu
{
protected:
sf::Color red;
sf::Color white;
std::vector<sf::Text> displayedText;
int currentOption{ 0 };
public:
virtual void draww(sf::RenderWindow& window) = 0;
virtual void clickButton() = 0;
virtual void moveUp() = 0;
virtual void moveDown() = 0;
};
class FirstMenu : public Menu
{
public:
FirstMenu(sf::RenderWindow& window)
{
sf::Text text;
sf::Font font;
if (!font.loadFromFile("arial.ttf"))
{
std::cout << "Font error. \n";
}
text.setFont(font);
text.setString("Play");
displayedText.push_back(text);
text.setString("Options");
displayedText.push_back(text);
displayedText[0].setFillColor(red);
displayedText[0].setPosition(20, 30);
displayedText[1].setPosition(30, 30);
}
virtual void clickButton()
{
switch (currentOption)
{
case 0:
std::cout << "Playing. \n";
break;
case 1:
std::cout << "Options. \n";
break;
}
}
virtual void moveUp()
{
currentOption++;
displayedText[currentOption].setFillColor(white);
for (int i = 0; i < displayedText.size(); i++)
{
if (i == currentOption)
{
displayedText[i].setFillColor(red);
}
}
}
virtual void moveDown()
{
currentOption--;
displayedText[currentOption].setFillColor(white);
for (int i = 0; i < displayedText.size(); i++)
{
if (i == currentOption)
{
displayedText[i].setFillColor(red);
}
}
}
virtual void draww(sf::RenderWindow& window)
{
if (!displayedText.empty())
{
for (int i = 0; i < displayedText.size(); i++)
{
window.draw(displayedText[i]); //Exception thrown here
}
}
}
};
int main()
{
sf::RenderWindow window(sf::VideoMode(500, 500), "SFML works!");
FirstMenu menu(window);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
menu.draww(window);
window.display();
}
return 0;
}
抛出异常时显示的文本是:
“位置 0x799B35BB 中的未处理异常 (sfml-graphics-2.dll)
0xC0000005:读取位置 0x00000004 时出现访问冲突
我能看到的主要问题是在 FirstMenu
的构造函数中你是
sf::Font font;
if (!font.loadFromFile("arial.ttf"))
{
std::cout << "Font error. \n";
}
text.setFont(font)
本质上是将文本的字体设置为本地字体对象。这是有问题的,因为 SFML 中的文本不会复制传入的字体资源。
SFML 关于文本 class 的文档说明了关于 setFont
The font argument refers to a font that must exist as long as the text
uses it. Indeed, the text doesn't store its own copy of the font, but
rather keeps a pointer to the one that you passed to this function. If
the font is destroyed and the text tries to use it, the behavior is
undefined.
还值得注意的是,形状和精灵的 setTexture
函数的行为类似,因为它不存储纹理资源的副本。
修复是为了确保字体对象在被文本对象使用时不会被破坏。
最简单的修复包括:
- 在 main 中加载字体并将字体传递给需要它的函数和对象。
- 如果您使用的是单一字体,那么有一个具有静态字体的全局函数,并且只构造和加载它一次。
- 如果需要多种字体并且您不想四处传递字体,那么您可以使用单独的字体资源管理器。
最近开始学习SFML。我想做的第一件事是一个简单的菜单 - 所以我为所有菜单创建了一个界面,包含受保护字段中其他菜单所需的一切。但是,我的代码有时会抛出异常,我不知道为什么。
#include <SFML/Graphics.hpp>
#include <iostream>
class Menu
{
protected:
sf::Color red;
sf::Color white;
std::vector<sf::Text> displayedText;
int currentOption{ 0 };
public:
virtual void draww(sf::RenderWindow& window) = 0;
virtual void clickButton() = 0;
virtual void moveUp() = 0;
virtual void moveDown() = 0;
};
class FirstMenu : public Menu
{
public:
FirstMenu(sf::RenderWindow& window)
{
sf::Text text;
sf::Font font;
if (!font.loadFromFile("arial.ttf"))
{
std::cout << "Font error. \n";
}
text.setFont(font);
text.setString("Play");
displayedText.push_back(text);
text.setString("Options");
displayedText.push_back(text);
displayedText[0].setFillColor(red);
displayedText[0].setPosition(20, 30);
displayedText[1].setPosition(30, 30);
}
virtual void clickButton()
{
switch (currentOption)
{
case 0:
std::cout << "Playing. \n";
break;
case 1:
std::cout << "Options. \n";
break;
}
}
virtual void moveUp()
{
currentOption++;
displayedText[currentOption].setFillColor(white);
for (int i = 0; i < displayedText.size(); i++)
{
if (i == currentOption)
{
displayedText[i].setFillColor(red);
}
}
}
virtual void moveDown()
{
currentOption--;
displayedText[currentOption].setFillColor(white);
for (int i = 0; i < displayedText.size(); i++)
{
if (i == currentOption)
{
displayedText[i].setFillColor(red);
}
}
}
virtual void draww(sf::RenderWindow& window)
{
if (!displayedText.empty())
{
for (int i = 0; i < displayedText.size(); i++)
{
window.draw(displayedText[i]); //Exception thrown here
}
}
}
};
int main()
{
sf::RenderWindow window(sf::VideoMode(500, 500), "SFML works!");
FirstMenu menu(window);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear();
menu.draww(window);
window.display();
}
return 0;
}
抛出异常时显示的文本是: “位置 0x799B35BB 中的未处理异常 (sfml-graphics-2.dll) 0xC0000005:读取位置 0x00000004 时出现访问冲突
我能看到的主要问题是在 FirstMenu
的构造函数中你是
sf::Font font;
if (!font.loadFromFile("arial.ttf"))
{
std::cout << "Font error. \n";
}
text.setFont(font)
本质上是将文本的字体设置为本地字体对象。这是有问题的,因为 SFML 中的文本不会复制传入的字体资源。
SFML 关于文本 class 的文档说明了关于 setFont
The font argument refers to a font that must exist as long as the text uses it. Indeed, the text doesn't store its own copy of the font, but rather keeps a pointer to the one that you passed to this function. If the font is destroyed and the text tries to use it, the behavior is undefined.
还值得注意的是,形状和精灵的 setTexture
函数的行为类似,因为它不存储纹理资源的副本。
修复是为了确保字体对象在被文本对象使用时不会被破坏。
最简单的修复包括:
- 在 main 中加载字体并将字体传递给需要它的函数和对象。
- 如果您使用的是单一字体,那么有一个具有静态字体的全局函数,并且只构造和加载它一次。
- 如果需要多种字体并且您不想四处传递字体,那么您可以使用单独的字体资源管理器。