You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 11:12:50