ArticxEngine.exe 中 0x777122D2 (ntdll.dll) 处未处理的异常:0xC0000005:访问冲突写入位置 0x00000004

2024-05-07

我完全不确定为什么在 VS2012 中运行程序时会出现此错误。 Visual Studio 似乎将问题引向sf::RenderWindow Articx::window; in Articx.cpp

ArticxEngine.exe 中 0x777122D2 (ntdll.dll) 处出现未处理的异常: 0xC0000005:访问冲突写入位置 0x00000004。

Code Articx.h

#pragma once

#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>

class Articx
{
    public:
        static void Start();
    private:
        static void GameLoop();

        static bool isExiting();

        enum ScreenState {before, splash1, splash2, splash3, menu, pause, playing, exit};
        static ScreenState currentState;

        static sf::RenderWindow window;
};

Code Articx.cpp

#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <iostream>
#include <string>
#include "Articx.h"

inline void Message(char message[]);
inline void CallError(int code, char message[]);

Articx::ScreenState Articx::currentState = Articx::before;
sf::RenderWindow Articx::window;

void Articx::Start()
{
    Message("Articx Engine 1.0 Initializing...");

    if(currentState != before)
        return;

    window.create(sf::VideoMode(800,600,32), "Articx Engine 1.0");
    currentState = playing;

    while (!isExiting())
    {
        Message("Engine Initialized");
        Articx::GameLoop();
    }

    window.close();
}

bool Articx::isExiting()
{
    if(currentState == exit)
        return true;
    else
        return false;
}

void Articx::GameLoop()
{
    sf::Event currentEvent;

    while ( window.pollEvent(currentEvent) )
    {
        switch(currentState)
        {
            case Articx::playing:
                {
                    window.clear(sf::Color(0,0,0));
                    window.display();

                    if ( currentEvent.type == sf::Event::Closed )
                        currentState = exit;
                    break;
                }
        }
    }

    window.display();
}

inline void CallError(int code, char message[])
{
    std::cout << "ERROR CODE - " << code << std::endl << message << std::endl << "Will now exit..." << std::endl;
    system("PAUSE");
}

inline void Message(char message[])
{
    std::cout << "AX-MESSAGE: " << message << std::endl;
}

Code main.cpp

#include "Articx.h"

using namespace std;

int main(int argc, char** argv)
{
    Articx::Start();
    return 0;
}

“底线”原因

未处理异常的原因是因为您将 Articx::window 定义为静态变量。

技术说明

抛出异常是因为构造 sf:RenderWindow 按以下顺序调用以下构造函数:

渲染窗口::渲染窗口()
窗口::窗口()
GlResource::GlResource()

GlResource::GlResource() 构造函数尝试锁定全局互斥体:

namespace
{
    // OpenGL resources counter and its mutex
    unsigned int count = 0;
    sf::Mutex mutex;
}


namespace sf
{
////////////////////////////////////////////////////////////
GlResource::GlResource()
{
    {
        // Protect from concurrent access
        Lock lock(mutex);

        // If this is the very first resource, trigger the global context initialization
        if (count == 0)
            priv::GlContext::globalInit();

        // Increment the resources counter
        count++;
    }

    // Now make sure that there is an active OpenGL context in the current thread
    priv::GlContext::ensureContext();
}

问题是你俩Arctix::窗口和 SFML 的sf::互斥体 互斥体是在程序初始化时构造的全局/静态变量。哪个先建造?在你的情况下你的window首先构造,因此 GlResource::GlResource() 构造函数尝试锁定无效的 sf::Mutex。由于全局/静态变量的构造顺序可能无法预测,因此最好在非全局位置创建 sf::RenderWindow 对象。

解决方案

在 main.cpp 中,在 main() 中创建 sf::RenderWindow 对象,并将引用传递给window通过 Articx::Start():

#include "Articx.h"

using namespace std;

int main(int argc, char** argv)
{
    sf::RenderWindow window;

    Articx::Start(window);
    return 0;
}

在Articx.h中,删除静态成员变量window,并展开Start() and 游戏循环()接受 sf::RenderWindow 引用:

#pragma once

#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>

class Articx
{
    public:
        static void Start(sf::RenderWindow &window);
    private:
        static void GameLoop(sf::RenderWindow &window);

        static bool isExiting();

        enum ScreenState {before, splash1, splash2, splash3, menu, pause, playing, exit};
        static ScreenState currentState;
};

在Articx.cpp中,删除全局定义window并修改Start() and 游戏循环()接受并使用传递的 sf::RenderWindow 引用:

void Articx::Start(sf::RenderWindow &window)
{
    Message("Articx Engine 1.0 Initializing...");

    if(currentState != before)
        return;

    window.create(sf::VideoMode(800,600,32), "Articx Engine 1.0");
    currentState = playing;

    while (!isExiting())
    {
        Message("Engine Initialized");
        Articx::GameLoop(window);
    }

    window.close();
}

. . .

void Articx::GameLoop(sf::RenderWindow &window)
{
    . . .
}

现在运行它可以正确显示窗口:

该窗口似乎有一个无限循环打印“引擎已初始化”,但我将其留给您:-)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ArticxEngine.exe 中 0x777122D2 (ntdll.dll) 处未处理的异常:0xC0000005:访问冲突写入位置 0x00000004 的相关文章

  • 为什么在连接两个字符串时 Python 比 C 更快?

    目前我想比较 Python 和 C 用来处理字符串的速度 我认为 C 应该比 Python 提供更好的性能 然而 我得到了完全相反的结果 这是 C 程序 include
  • 如何在多线程C++ 17程序中交换两个指针?

    我有两个指针 pA 和 pB 它们指向两个大的哈希映射对象 当pB指向的哈希图完全更新后 我想交换pB和pA 在C 17中 如何快速且线程安全地交换它们 原子 我是 c 17 的新手 2个指针的原子无等待交换可以通过以下方式实现 inclu
  • 如何捕获未发送到 stdout 的命令行文本?

    我在项目中使用 LAME 命令行 mp3 编码器 我希望能够看到某人正在使用什么版本 如果我只执行 LAME exe 而不带参数 我会得到 例如 C LAME gt LAME exe LAME 32 bits version 3 98 2
  • 为什么pow函数比简单运算慢?

    从我的一个朋友那里 我听说 pow 函数比简单地将底数乘以它的指数的等价函数要慢 例如 据他介绍 include
  • ComboBox DataBinding 导致 ArgumentException

    我的几个类对象 class Person public string Name get set public string Sex get set public int Age get set public override string
  • C++ 是否可以在 MacOS 上与 OpenMP 和 boost 兼容?

    我现在已经尝试了很多事情并得出了一些结论 也许 我监督了一些事情 但似乎我无法完成我想要的事情 问题是 是否有可能使用 OpenMP 和 boost 在 MacOS High Sierra 上编译 C 一些发现 如果我错了请纠正我 Open
  • IdentityServer 4 对它的工作原理感到困惑

    我阅读和观看了很多有关 Identity Server 4 的内容 但我仍然对它有点困惑 因为似乎有很多移动部件 我现在明白这是一个单独的项目 它处理用户身份验证 我仍然不明白的是用户如何注册它 谁存储用户名 密码 我打算进行此设置 Rea
  • 查找进程的完整路径

    我已经编写了 C 控制台应用程序 当我启动应用程序时 不使用cmd 我可以看到它列在任务管理器的进程列表中 现在我需要编写另一个应用程序 在其中我需要查找以前的应用程序是否正在运行 我知道应用程序名称和路径 所以我已将管理对象搜索器查询写入
  • 函数参数的默认参数是否被视为该参数的初始值设定项?

    假设我有这样的函数声明 static const int R 0 static const int I 0 void f const int r R void g int i I 根据 dcl fct default 1 如果在参数声明中指
  • Visual Studio 在构建后显示假错误

    我使用的是 Visual Studio 2017 构建后 sln在调试模式下 我收到错误 但是 当我通过双击错误列表选项卡中的错误来访问错误时 错误会从页面中消失 并且错误数量也会减少 我不太确定这种行为以及为什么会发生这种情况 有超过 2
  • unordered_map 中字符串的 C++ 哈希函数

    看起来 C 标准库中没有字符串的哈希函数 这是真的 在任何 c 编译器上使用字符串作为 unordered map 中的键的工作示例是什么 C STL提供模板专业化 http en cppreference com w cpp string
  • 为什么我的单选按钮不起作用?

    我正在 Visual C 2005 中开发 MFC 对话框应用程序 我的单选按钮是 m Small m Medium 和 m Large 它们都没有在我的 m Summary 编辑框中显示应有的内容 可能出什么问题了 这是我的代码 Pizz
  • 保护 APK 中的字符串

    我正在使用 Xamarin 的 Mono for Android 开发一个 Android 应用程序 我目前正在努力使用 Google Play API 添加应用内购买功能 为此 我需要从我的应用程序内向 Google 发送公共许可证密钥
  • 高效列出目录中的所有子目录

    请参阅迄今为止所采取的建议的编辑 我正在尝试使用 WinAPI 和 C 列出给定目录中的所有目录 文件夹 现在我的算法又慢又低效 使用 FindFirstFileEx 打开我正在搜索的文件夹 然后我查看目录中的每个文件 使用 FindNex
  • 使 Guid 属性成为线程安全的

    我的一个类有一个 Guid 类型的属性 该属性可以由多个线程同时读写 我的印象是对 Guid 的读取和写入不是原子的 因此我应该锁定它们 我选择这样做 public Guid TestKey get lock testKeyLock ret
  • String.Empty 与 "" [重复]

    这个问题在这里已经有答案了 可能的重复 String Empty 和 有什么区别 https stackoverflow com questions 151472 what is the difference between string
  • 实体框架中的“it”是什么

    如果以前有人问过这个问题 请原谅我 但我的任何搜索中都没有出现 它 我有两个数据库表 Person 和 Employee 对每个类型的表进行建模 例如 Employee is a Person 在我的 edmx 设计器中 我定义了一个实体
  • 这个可变参数模板示例有什么问题?

    基类是 include
  • Objective-C / C 给出枚举默认值

    我在某处读到过关于给枚举默认值的内容 如下所示 typedef enum MarketNavigationTypeNone 0 MarketNavigationTypeHeirachy 1 MarketNavigationTypeMarke
  • 灵气序列解析问题

    我在使用 Spirit Qi 2 4 编写解析器时遇到一些问题 我有一系列键值对以以下格式解析

随机推荐