Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Access Violation at Runtime when creating Texture object in Resource Manager  (Read 3836 times)

0 Members and 2 Guests are viewing this topic.

Safis

  • Newbie
  • *
  • Posts: 2
    • View Profile
I'm running into an access violation in my resource manager class when it tries to declare a temporary sf::Texture object. I can't quite figure out why the error is occurring, although I suspect it may be related to the fact that I'm using an extern instance of the class so that it can be accessed by all other classes.

I created a simple project including only the resource manager class and a fairly basic main.cpp in order to be sure that this is where the problem is coming from, and sure enough, it is.

The offending line is at line 76 in ResourceManager.cpp:
sf::Texture temp;
resulting in an error message of:
Unhandled exception at 0x77242262 in FindingTheProblem.exe: 0xC0000005: Access violation writing location 0x00000004.

I think what's happening is, before the main function even begins to execute, the constructor of the ResourceManager is being called. It attempts to load in a default "error" image, texture, and sound for use when loading of a specified resource fails. The code to load each is identical except for what type of object it is creating and which map it is storing it in, and yet there are no problems with the image or the sound. Changing the order in which they are called also doesn't make a difference. It's only the texture that causes the violation. Why is simply declaring an sf::Texture object causing an access violation, and in that case, why do the sf::Image and sf::SoundBuffer not cause the same problem? Any ideas on how I can fix this?

For what it's worth, I'm using SFML 2.0-RC and C++, in Visual Studio 2010 running on Windows 7 (64-bit).

Here are the significant parts of my code. I'll attach the full code as well. I'm aware it's not the most efficient, and there are more features I plan to add to my resource manager, but I'm just trying to get it functioning in this basic state for now.

ResourceManager.h
class ResourceManager {
...
};

extern ResourceManager Resources;                                       // Create a global instance of this class

#endif

ResourceManager.cpp
#include "ResourceManager.h"

ResourceManager Resources;

// Constructor
ResourceManager::ResourceManager()
{
        //Load in the error-default data
        loadImage("ERR_DEFAULT", "sprites/errdefault.png");
        loadTexture("ERR_DEFAULT", "sprites/errdefault.png");
        loadSound("ERR_DEFAULT", "sounds/errdefault.wav");
}

...

void ResourceManager::addTexture(const std::string& key, const sf::Texture& data)
{
        textureBank.insert(std::make_pair(key, data));
}

...

bool ResourceManager::loadTexture(const std::string& key, const std::string& path)
{
        //Ensure key is non-empty
        if(key == "")
                return false;

        //Check whether key is already in bank. If it is, do not load data.
        if(textureBank.find(key) != textureBank.end())
                return false;

        //Create a temporary texture object
        sf::Texture temp;

        //Ensure file loads successfully
        if(!temp.loadFromFile(path))
                return false;

        //Add the data to the bank
        addTexture(key, temp);
        return true;
}

Thanks a lot for any help you can offer!

[attachment deleted by admin]

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11033
    • View Profile
    • development blog
    • Email
Your problem is the global scope.
What exactly goes wrong inside SFML I can't tell you, there's a bug on Linux that you can't instantiate an sf::Texture before you create a sf::RenderWindow object, maybe it's somewhere related to this.
But it actually doesn't matter since global variables are really not the best software design idea. But I don't feel like write down all the contras etc, so I only suggest to you, if you need to use global variables make it at least a singleton. Also I'd suggest to not load the images with in the constructor but to create another function like init() and call it from within the main() function.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Safis

  • Newbie
  • *
  • Posts: 2
    • View Profile
Well this is interesting, thank you for your feedback. I have only heard of the term "singleton" in passing before, but never investigated what it is. I'll have to spend some time figuring this one out, it looks like.

But in the meantime, I moved the content of my ResourceManager constructor into a separate init() function, which I call from main() after creating my RenderWindow, and now it loads just fine! Except, now I find that closing the window is causing an access violation, which may be a completely separate issue. I don't suppose you'd know what would be behind that?

It's giving the error message:
Unhandled exception at 0x774e1c1d in FindingTheProblem.exe: 0xC0000005: Access violation reading location 0xfeeefef6.
and the program flow stops in xmemory at the end of this function:
                // TEMPLATE FUNCTION _Destroy
template<class _Ty> inline
        void _Destroy(_Ty _FARQ *_Ptr)
        {       // destroy object at _Ptr
        _Ptr->~_Ty();
        }

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11033
    • View Profile
    • development blog
    • Email
I bet it's a problem with destroing OpenGL contextes, SFML has some issues with handling them right.

Do you use some text rendering and the default font of SFML?
If so the problem is common and unfortunatly still not really fixed by SFML. The solution would then be to either not use the default font or to link statically.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

 

anything