未处理的异常在0x777122D2(ntdll.dll)在ArticxEngine.exe:0xC0000005:访问冲突写入位置0x00000004 [英] Unhandled exception at 0x777122D2 (ntdll.dll) in ArticxEngine.exe: 0xC0000005: Access violation writing location 0x00000004

查看:603
本文介绍了未处理的异常在0x777122D2(ntdll.dll)在ArticxEngine.exe:0xC0000005:访问冲突写入位置0x00000004的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我完全不确定为什么我得到这个错误在VS2012当我运行我的程序。 Visual Studio似乎将问题导向 sf :: RenderWindow Articx :: window; 在 Articx.cpp


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


代码 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();

枚举ScreenState {before,splash1,splash2,splash3,menu,pause,playing,exit};
static Sc​​reenState currentState;

static sf :: RenderWindow window;
};

代码 Articx.cpp

  #include< SFML / Graphics.hpp> 
#include< SFML / System.hpp>
#include< SFML / Window.hpp>
#include< iostream>
#include< string>
#includeArticx.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())
{
消息(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 - <<代码< std :: endl<消息< std :: endl< 现在将退出...< std :: endl;
system(PAUSE);
}

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

代码 main.cpp

  #includeArticx.h

using namespace std;

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


解决方案

行原因



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



技术说明



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


RenderWindow :: RenderWindow()

Window :: Window()

GlResource :: GlResource()


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

 命名空间
{
// OpenGL资源计数器及其互斥量
unsigned int count = 0;
sf :: Mutex mutex;
}


命名空间sf
{
////////////////////// //////////////////////////////////////
GlResource :: GlResource()
{
{
//保护并发访问
锁定锁(mutex);

//如果这是第一个资源,触发全局上下文初始化
if(count == 0)
priv :: GlContext :: globalInit();

//增加资源计数器
count ++;
}

//现在确保当前线程中有一个活动的OpenGL上下文
priv :: GlContext :: ensureContext();
}

问题是您的 Articx :: window 和SFML的 sf :: Mutex mutex 是在程序初始化时构建的全局/静态变量。哪一个首先构建?在你的情况下,你的窗口是首先构造的,所以GlResource :: GlResource()构造函数试图锁定一个无效的sf :: Mutex。因为全局/静态变量的构造顺序可能是不可预测的,最好在非全局位置创建您的sf :: RenderWindow对象。



解决方案



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

  #includeArticx.h

using namespace std ;

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

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



在Articx.h中,删除静态成员变量并展开 Start() Gameloop()接受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();

枚举ScreenState {before,splash1,splash2,splash3,menu,pause,playing,exit};
static Sc​​reenState currentState;
};

在Articx.cpp中,删除窗口的全局定义, em> Start() Gameloop()接受并使用传递的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())
{
消息(Engine Initialized);
Articx :: GameLoop(window);
}

window.close();
}

。 。 。

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

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



>



窗口似乎有一个无尽的循环打印引擎初始化,但我给你留下: - )。


I'm completely unsure of why I'm getting this error in VS2012 when I run my program. Visual Studio seemed to direct the problem towards sf::RenderWindow Articx::window; in Articx.cpp

Unhandled exception at 0x777122D2 (ntdll.dll) in ArticxEngine.exe: 0xC0000005: Access violation writing location 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;
}

解决方案

The "Bottom Line" Reason

The reason for the unhandled exception is because you defined Articx::window as a static variable.

The Technical Explanation

The exception was thrown because constructing an sf:RenderWindow invokes the following constructors in this order:

RenderWindow::RenderWindow()
Window::Window()
GlResource::GlResource()

The GlResource::GlResource() constructor attempts to lock a global mutex:

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();
}

The problem is that both your Articx::window and SFML's sf::Mutex mutex are global/static variables that are constructed at program initialization time. Which one gets constructed first? In your case your window was constructed first, so the GlResource::GlResource() constructor attempted to lock an invalid sf::Mutex. Because the order of construction of global/static variables can be unpredictable, it is best to create your sf::RenderWindow object in a non-global location.

The Solution

In main.cpp, create your sf::RenderWindow object within main(), passing a reference to window via Articx::Start():

#include "Articx.h"

using namespace std;

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

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

In Articx.h, remove the static member variable window, and expand Start() and Gameloop() to accept an sf::RenderWindow reference:

#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;
};

In Articx.cpp, remove the global definition of window and modify Start() and Gameloop() to accept and use the passed sf::RenderWindow reference:

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)
{
    . . .
}

Running it now displays the window correctly:

The window seems to have an endless loop printing "Engine Initialized", but I leave that to you :-).

这篇关于未处理的异常在0x777122D2(ntdll.dll)在ArticxEngine.exe:0xC0000005:访问冲突写入位置0x00000004的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆