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

SFML实现AVL树可视化程序运行报ntdll.dll 0xC0000005错误求助

错误原因

你遇到的0xC0000005访问冲突是典型的空指针解引用错误,写入地址0x00000004说明程序尝试对空指针偏移4字节的地址执行写入操作,触发崩溃的核心原因有两个:

  • 第一:字体加载没有做合法性校验
    代码中直接调用font.loadFromFile("CyrilicOld.TTF"),如果对应路径下不存在该字体文件,font对象就处于无效状态,后续draw函数中为sf::Text设置字体、计算文本边界时就会触发空指针访问。
  • 第二:事件循环逻辑存在未定义行为
    你的内层循环写为while (window.pollEvent(event) || change),当没有待处理事件但change为true时,event变量是未初始化的,此时直接访问event.type会读取垃圾值,甚至触发内存访问错误。

修复方案

1. 增加字体加载校验

修改main函数中的字体加载逻辑,加载失败直接抛出错误提示,避免后续使用无效字体:

// 替换你原来的font.loadFromFile行
if (!font.loadFromFile("CyrilicOld.TTF")) {
    // 也可以替换为系统自带字体路径,比如Windows下写"C:/Windows/Fonts/arial.ttf"
    std::cerr << "字体加载失败,请检查字体文件路径是否正确" << std::endl;
    return -1;
}

2. 修正事件循环逻辑

把事件处理和页面刷新逻辑拆分,不要在无事件的时候访问未初始化的event:

while (window.isOpen()) {
    sf::Event event;
    while (window.pollEvent(event)) {
        // 所有和event相关的逻辑都移到这里面
        if (event.type == Event::Closed || Keyboard::isKeyPressed(Keyboard::Escape)) {
            window.close();
        }
    }

    float del_tim = clock.getElapsedTime().asMicroseconds();
    del = del_tim / 4e4;
    clock.restart();
    tim += del_tim;
    kadr++;
    if (tim > 1e6) {
        tim -= 1e6;
        kadr = 0;
    }

    // 持续按下的输入检测放在这里
    if (Keyboard::isKeyPressed(Keyboard::Dash)) {
        view.zoom(1.03f);
        speed = speed * 1.03f;
        wid = wid * 1.03f;
        change = true;
    }
    if (Keyboard::isKeyPressed(Keyboard::Equal)) {
        view.zoom(0.97f);
        speed = speed * 0.97f;
        wid = wid * 0.97f;
        change = true;
    }
    if (Keyboard::isKeyPressed(Keyboard::Left)) {
        view.move(Vector2f(-speed * del, 0));
        wid += speed * del;
        change = true;
    }
    if (Keyboard::isKeyPressed(Keyboard::Down)) {
        view.move(Vector2f(0, speed * del));
        change = true;
    }
    if (Keyboard::isKeyPressed(Keyboard::Up)) {
        view.move(Vector2f(0, -speed * del));
        change = true;
    }
    if (Keyboard::isKeyPressed(Keyboard::Right)) {
        view.move(Vector2f(speed * del, 0));
        wid += speed * del;
        change = true;
    }
    if (Mouse::isButtonPressed(Mouse::Left)) {
        for (int i = 0; i < 10; i++) {
            int key = rand() - rand();
            t = add(key, t);
        }
        change = true;
    }
    if (Keyboard::isKeyPressed(Keyboard::A)) {
        int key;
        cin >> key;
        t = add(key, t);
        change = true;
    }
    if (Keyboard::isKeyPressed(Keyboard::E)) {
        int key;
        cin >> key;
        t = erase(key, t);
        change = true;
    }
    if (Keyboard::isKeyPressed(Keyboard::N)) {
        view.zoom(wid_n / wid);
        speed *= wid_n / wid;
        wid = wid_n;
    }

    if (change) {
        window.setView(view);
        window.clear(Color(128, 106, 89));
        if (t != nullptr) { // 空树的时候跳过渲染,避免多余调用
            get_edg(t, 0, get_h(t));
            wid_n = get(t, 0, get_h(t));
            hei_n = get_h(t) * h_size;
        }
        window.display();
        change = false; // 打开这行注释,避免无限刷新占用CPU
    }
}

可选优化:修正AVL树插入逻辑

你当前的插入逻辑是把小于当前节点的值放到右子树,大于的放到左子树,和常规AVL树的实现相反,如果需要符合常规逻辑可以修改add函数的判断:

if (t->c > c) {
    t->l = add(c, t->l); // 原来写的t->r,改成t->l
} else {
    t->r = add(c, t->r); // 原来写的t->l,改成t->r
}

内容的提问来源于stack exchange,提问作者Bảo DG

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 11:06:04