使用Visual Studio C++与SFML加载字体时程序崩溃求助
问题分析与解决
你的崩溃核心原因是SFML的Text对象仅持有Font的引用,而非拷贝:
- 在
generateTitle函数中,titleFont是局部变量,函数执行完毕后会被销毁释放内存。 - 你创建的
titleText通过setFont(titleFont)绑定了这个局部Font的引用,当函数返回后,titleText持有的Font指针变成悬空指针,调用window.draw时访问无效内存,触发0xC0000005访问违例。
另外还有个潜在的路径问题:字符串里的\f是转义字符(换页符),实际路径会被解析成filesfont.ttf,应该改成files\\font.ttf或者使用原始字符串R"(files\font.ttf)"。
修复方案
方案1:将Font的生命周期延长至Text使用期间
把Font放在main函数中创建,传递给生成Text的函数:
#include <iostream> #include "SFML/Graphics.hpp" #include <string> sf::Text generateTitle(sf::Font& titleFont) { sf::Text titleText; titleText.setFont(titleFont); titleText.setString("WELCOME TO MINESWEEPER!"); titleText.setCharacterSize(24); titleText.setFillColor(sf::Color::White); titleText.setStyle(sf::Text::Bold | sf::Text::Underlined); return titleText; } int main() { sf::RenderWindow window(sf::VideoMode(800, 600), "SFML window", sf::Style::Close); // 在这里创建Font,生命周期覆盖整个Text的使用过程 sf::Font titleFont; // 修复路径转义问题 if (!titleFont.loadFromFile("files\\font.ttf")) { std::cerr << "Failed to load font!" << std::endl; return 1; } sf::Text titleText = generateTitle(titleFont); // 添加主循环,避免窗口一闪而过 while (window.isOpen()) { sf::Event event; while (window.pollEvent(event)) { if (event.type == sf::Event::Closed) window.close(); } window.clear(sf::Color::Blue); window.draw(titleText); window.display(); } return 0; }
方案2:使用全局Font(简单但不推荐大型项目)
把titleFont声明为全局变量,确保它在程序运行期间始终存在:
#include <iostream> #include "SFML/Graphics.hpp" #include <string> sf::Font titleFont; // 全局Font sf::Text generateTitle() { if (!titleFont.loadFromFile("files\\font.ttf")) { std::cerr << "Failed to load font!" << std::endl; } sf::Text titleText; titleText.setFont(titleFont); titleText.setString("WELCOME TO MINESWEEPER!"); titleText.setCharacterSize(24); titleText.setFillColor(sf::Color::White); titleText.setStyle(sf::Text::Bold | sf::Text::Underlined); return titleText; } int main() { sf::RenderWindow window(sf::VideoMode(800, 600), "SFML window", sf::Style::Close); sf::Text titleText = generateTitle(); while (window.isOpen()) { sf::Event event; while (window.pollEvent(event)) { if (event.type == sf::Event::Closed) window.close(); } window.clear(sf::Color::Blue); window.draw(titleText); window.display(); } return 0; }
额外注意
- 一定要检查
loadFromFile的返回值,确认Font加载成功,否则即使修复了生命周期问题,依然可能因为Font未加载导致崩溃。 - 原代码缺少主循环,窗口会创建后立即关闭,添加主循环才能正常显示窗口内容。
内容的提问来源于stack exchange,提问作者jmcgraww
相关产品推荐
相关产品推荐

