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

Author Topic: Sprite properties turn into 'unable to read memory'  (Read 6645 times)

0 Members and 5 Guests are viewing this topic.

Alex1011

  • Newbie
  • *
  • Posts: 6
    • View Profile
Sprite properties turn into 'unable to read memory'
« on: September 10, 2014, 11:58:29 am »
Hello guys,

I have a problem with my sf::Sprite in my own class(CEditbox).
I figured out that as soon as i use any command with my variable 'text' of sf::Text the sprite's sf::Drawable and sf::Transformable property '__vfptr' turns 'unable to read memory'. Every other property remains fine.
Therefore i get the following error, if i try to draw the sprite:

Unhandled exception at 0x0F134CBE (sfml-graphics-d-2.dll) in Editor.exe: 0xC0000005: Access violation reading location 0x00000004.

This is the class, where the editboxes are stored:

class CControls{
public:
        CControls(sf::RenderWindow& paWindow, CAssetmanager& paAm);
        ~CControls(void);

        void addEditbox(int paType, sf::Vector2i paPos);
private:
        std::vector<std::shared_ptr<CEditbox>> editboxes;

        sf::RenderWindow& window;
        CAssetmanager& am;
};

CControls::CControls(sf::RenderWindow& paWindow, CAssetmanager& paAm) : window(paWindow), am(paAm) {

}

CControls::~CControls(void){
}

void CControls::addEditbox(int paType, sf::Vector2i paPos){
        editboxes.push_back(std::shared_ptr<CEditbox>(new CEditbox(paType, paPos, window, am)));
}

This is the class itself:

class CEditbox {
public:
        CEditbox(int paType, sf::Vector2i paPos, sf::RenderWindow& paWindow, CAssetmanager& paAm);
        ~CEditbox(void);

        void setText(std::string paText);
private:
        sf::Font& font;
        sf::Text text;

        sf::RenderWindow& window;
        CAssetmanager& am;
};

CEditbox::CEditbox(int paType, sf::Vector2i paPos, sf::RenderWindow& paWindow, CAssetmanager& paAm) : window(paWindow),  font(paAm.getFont()), am(paAm),line(sf::RectangleShape(sf::Vector2f(2, 20))){
        switch(paType){//templates for editboxes
        case 1:
sprite.setTexture(paAm.getTexture(2));
sprite.setTextureRect(paAm.getTextureRect(209));

                        text.setFont(font);
                        text.setCharacterSize(20);
                        text.setPosition(paPos.x + 5, paPos.y + 5);
                        text.setColor(sf::Color::Black);

                        break;
        }
        text.setString(sf::String(""));

        sprite.setPosition(pos.x, pos.y);
        size = sf::Vector2i(sprite.getTextureRect().width, sprite.getTextureRect().height);
}

CEditbox::~CEditbox(void){

}

void CEditbox::setText(std::string paText){
        text.setString(paText);
}
 

I showed only the most important parts of the code (to my mind). If i completly comment all 'text' commands out, everything works fine.
What could be the problem?
Im using MVS2012 and the dynamic version of sfml.

edit:completly modified
« Last Edit: September 11, 2014, 05:53:06 pm by Alex1011 »

Strelok

  • Full Member
  • ***
  • Posts: 139
    • View Profile
    • GitHub
Re: Sprite has unreadable memory (__vfptr)
« Reply #1 on: September 10, 2014, 12:29:47 pm »

Alex1011

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: Sprite properties turn into 'unable to read memory'
« Reply #2 on: September 11, 2014, 05:55:26 pm »
If the post still not goes by with the forum's rules please let me know or any further improvements should be made. This issue really drives me crazy  :-[

Holland

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Sprite properties turn into 'unable to read memory'
« Reply #3 on: September 11, 2014, 08:08:38 pm »
0x00000004 means that the address of the class you're using is probably 0x00000000. This means that you're using a pointer and that you forgot to initialise this!

Look where you're using the instance CEditBox, check if it is using -> and that new is added.

This is probably what you're dealing with
CEditBox *t_EditBox;
t_EditBox->DoSomethingWithText();
This is what it needs to become
CEditBox *t_EditBox = new CEditBox();
t_EditBox->DoSomethingWithText();

//.. And when you're done using this editbox..
delete t_EditBox;
Or simply:
CEditBox t_EditBox = CEditBox();
t_EditBox.DoSomethingWithText();
Then deleting will be handled for you when you leave the scope

Alex1011

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: Sprite properties turn into 'unable to read memory'
« Reply #4 on: September 11, 2014, 08:36:44 pm »
Hello Holland, thank you for your reply.

Im currently using your advice in a slightly other way (smartpointer on a new object instance):
editboxes.push_back(std::shared_ptr<CEditbox>(new CEditbox(paType, paPos, window, am)));
I can do anything with my editbox-object such as 'setText', 'isActiv' or anything else, but my sprite variable gets corrupted on it's __vfptr property (all other properties like texture or the position is just fine!), therefore the pointer should be initialised correctly.

A simple assignment will fail due it's missing '=' operator.

edit: I already tried unique_ptr and raw pointers, but the issue remains.
« Last Edit: September 11, 2014, 09:47:25 pm by Alex1011 »

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Sprite properties turn into 'unable to read memory'
« Reply #5 on: September 11, 2014, 09:19:46 pm »
...
This is what it needs to become
CEditBox *t_EditBox = new CEditBox();
t_EditBox->DoSomethingWithText();

//.. And when you're done using this editbox..
delete t_EditBox;
Manual memory management - eeek. :-(
Use std::unique_ptr / std::make_unique .
RAII is a good thing.
If I see "delete foo" or "delete[] foo" in modern C++, I'm instantly thinking "you're doing it wrong"..
« Last Edit: September 11, 2014, 09:23:31 pm by Jesper Juhl »

Alex1011

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: Sprite properties turn into 'unable to read memory'
« Reply #6 on: September 12, 2014, 04:31:43 pm »
Guys, i tried somethin new.

I replaced my text variable with a unique_ptr. This solves the sprite issue! But now I got another one, somethings really bad in this code.

The problem is, i can't set a font to my text. The font is managed in the assetmanager and is valid. I have no problems using the font on other objects. I checked my font variable which is of type sf::Font& and it is valid the whole time, but if I try to set the font to my text, the properties of font remain "unable to read memory"

This is my code now:
class CEditbox {
public:
        CEditbox(int paType, sf::Vector2i paPos, sf::RenderWindow& paWindow, CAssetmanager& paAm);      ~CEditbox(void);
private:
        sf::Font& font;
        std::unique_ptr<sf::Text> text;

        sf::RenderWindow& window;
        CAssetmanager& am;
};

CEditbox::CEditbox(int paType, sf::Vector2i paPos, sf::RenderWindow& paWindow, CAssetmanager& paAm) : window(paWindow),  font(paAm.getFont()), am(paAm),line(sf::RectangleShape(sf::Vector2f(2, 20))){
        active = false;
        visible = false;
        pos = paPos;

        std::unique_ptr<sf::Text> text(new sf::Text("ok", font, 20));
        (*text).setFont(paAm.getFont());
        sf::Text text2 = sf::Text("ok", font, 20);

        switch(paType){//templates for editboxes
                case 1:

                        (*text).setFont(font);
                        (*text).setCharacterSize(20);
                        (*text).setPosition(paPos.x + 5, paPos.y + 5);
                        (*text).setColor(sf::Color::Black);

                        break;
        }

        (*text).setString(sf::String(""));
}

Those lines before the switch statement are there for test purpose. The issue occurs on both, on the smartpointer variable text and the normal object text2, i cannot set the font to them. But the font isn't deleted and the address in my font variable is valid! All other properties of the text variables are valid too.

Thank you for your help and patience.

AlexAUT

  • Sr. Member
  • ****
  • Posts: 396
    • View Profile
Re: Sprite properties turn into 'unable to read memory'
« Reply #7 on: September 12, 2014, 06:23:16 pm »
Have a look at this articel: http://en.wikipedia.org/wiki/Variable_shadowing

You are creating a "new" local variable "text" in your constructor instead of modifying the member variable. To avoid this issue in the future I suggest you to use a prefix for member variables, for example mText/m_text...

And learn to interpret errors of your compiler/debugger/OS. If you get "unable to read memory" from a pointer check if its not "nullptr" or pointing to an not existing object (not possible with smartpointer but with normal pointers/ref)


AlexAUT
« Last Edit: September 12, 2014, 06:27:04 pm by AlexAUT »

Alex1011

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: Sprite properties turn into 'unable to read memory'
« Reply #8 on: September 12, 2014, 07:09:16 pm »
Hello Alex,

I read your article and tried other names for the affecting variables. This is not the problem, the issue remains  :( This is the code i have changed.

CEditbox::CEditbox(int paType, sf::Vector2i paPos, sf::RenderWindow& paWindow, CAssetmanager& paAm) : window(paWindow),  mFont(paAm.getFont()), am(paAm),line(sf::RectangleShape(sf::Vector2f(2, 20))){
        std::unique_ptr<sf::Text> mText(new sf::Text("ok", mFont, 20));

        switch(paType){//templates for editboxes
                case 1:
                        (*mText).setFont(mFont);
                        (*mText).setCharacterSize(20);
                        (*mText).setPosition(paPos.x + 5, paPos.y + 5);
                        (*mText).setColor(sf::Color::Black);

        }

        (*mText).setString(sf::String(""));
}

I have to create the 'new' variable, otherwise mText would be a nullptr, i tried it. Because there is no existing instance of a variable text.

I know that a "unable to read memory" error will most times be a nullptr issue. but mFont is no nullptr. I even compared the address of the mFont variable with my address in the assetmanger class and it is the same. This font is used by other controls like buttons and works perfectly.

Thank you for your answer, maybe you have some more suggestions? Or did I misunderstood something?

AlexAUT

  • Sr. Member
  • ****
  • Posts: 396
    • View Profile
Re: Sprite properties turn into 'unable to read memory'
« Reply #9 on: September 12, 2014, 07:27:47 pm »
No I meant you are creating a local variable with this line which shadows the member variable:

std::unique_ptr<sf::Text> mText(new sf::Text("ok", mFont, 20));

This line should be

mText = std::unique_ptr<sf::Text>(new sf::Text("ok", mFont, 20)); //std::make_unique if supported by your compiler (c++14)

or use it in the initializer list of the constructor:

mText(new sf::Text("ok", mFont, 20))


AlexAUT


Alex1011

  • Newbie
  • *
  • Posts: 6
    • View Profile
Re: Sprite properties turn into 'unable to read memory'
« Reply #10 on: September 12, 2014, 07:38:32 pm »
Thank you for the quick answer.

I replaced the affecting line with your suggestion:
        mText = std::unique_ptr<sf::Text>(new sf::Text("ok", mFont, 20));

but the issue remains  :(
mText has the right charsize and the right string "ok", but the font is still unreadable. And i'm sure mFont is valid, because im using it in another class, where everything works fine.