Unhandled exception at 0x777122D2 (ntdll.dll) in ArticxEngine.exe: 0xC0000005: Access violation writing location 0x00000004
c++, sfml
Solution
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 :-).
Problem
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; } ```