SFML Array of Sprites

closed account (EhqpDjzh)
So I am writing a map generation algorithm (with SFML), and it seems the problem is in here:
1
2
3
4
5
6
7
8
9
10
11
12
Sprite sprites[32][32];
void genmap(){
	Texture grasstiletex;
	grasstiletex.loadFromFile("data/grasstile.png");
	for (int x=0; x<32; x++){
		for (int y=0; y<32; y++){  //I already commented out every combination possible of these sprite functions, same error.
		sprites[x][y].setTexture(grasstiletex);
		sprites[x][y].setTextureRect(IntRect(0,0,32,32));
		sprites[x][y].setPosition(Vector2f(32*x,32*y));
		}
	}
}

But when I run it I get:
 
Unhandled exception at 0x69791f34 in sfmlproject.exe: 0xC0000005: Access violation reading location 0x001b5000.
The texture does not get copied to your sprites. The sprites all refer to the same texture.

This means the texture must have a lifetime that exceeds all of the sprites which use it. IE: The texture must not be destroyed until there are no more sprites using it.

Your texture is local to genmap... which means as soon as genmap exits, the texture goes away. And all your sprites which are using it are now trying to use a texture that no longer exists. Hence the access violation.
It doesn't lie, you're trying to access an element in the array that doesn't exist. You need to change your for loop conditions so they don't go out of bounds. They'll start from sprites[0][0] then get up to sprites[0][32] , there is no element at [0][32] so you get your access violation error.

Now, expanding this to some advice. 1.) Don't use multidimensional arrays, ever. Many people hate them, I hate them, you should hate them.

http://www.cplusplus.com/forum/articles/17108/

2.) In this case you should be fine using

a.) A simple one-dimensional array sf::Sprite sprites[1024];

b.) A one-dimensional vector std::vector<sf::Sprite> sprites;
With a vector you can have all sorts of map sizes, as vectors are re-sizable. The only issue I've run into with using a vector is that sometimes if you have a lot them ( like a 1000x1000 tilemap ) that vector can run out of space with its given piece of memory. ( There's a proper word "piece of memory" but it's no longer in my vocabulary ) If you only want around a 1000 sprites, however, then you don't need to worry about that.

As for looping through either of these containers

a.)

1
2
3
4
for(int i = 0; i <= numberOfSprites; i++)
{
     // do something with your sprite
}


b.)

1
2
3
4
5
6
7
8
9
for(auto i = sprites.begin(); i != sprites.end(); i++)
{
   // auto will make 'i' as type std::vector<sf::Sprite>::iterator
   // It's a pain to type that out so auto is handy
   // Since 'i' is an iterator, you'll have to use '->' operator like below
   i-><some function call here>;
   // Or you can de-reference it
  *i.<some function call here>
}
I don't think he's going out of bounds in his array. At least not in the code he posted.
@Disch

My bad, you're right, apologies very late over here. Although I'd still be willing to bet he's doing it somewhere ;)

All the same, I hope he takes some of that in and makes some changes.

EDIT: I suppose issues with pointers could also bring up that message.
Last edited on
closed account (EhqpDjzh)
I appreciate everbodys' contributions, Disch was right, After placing genmap into my main function, I had no issues.
closed account (EhqpDjzh)
Shit. False alarm, my bad. After running the code I get the same error, but when I comment out:
//grasstiletex.loadFromFile("data/grasstile.png");
It runs just fine, I understand the whole thing about making the texture live longer than the sprite, but I can't load a file. I don't think the issue is that it can't find the file I'm trying to load, but the error says:
Unhandled exception at 0x69251f34 in sfmlproject.exe: 0xC0000005: Access violation reading location 0x001d5000.
And just for reference, here is my main function:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
int main(){
	//genmap
	Texture grasstiletex;
	grasstiletex.loadFromFile("data/grasstile.png");
	//
	for (int x=0; x<32; x++){
		for (int y=0; y<32; y++){
		sprites[x][y]=Sprite();	
		sprites[x][y].setTexture(grasstiletex);
		sprites[x][y].setTextureRect(IntRect(0,0,32,32));
		sprites[x][y].setPosition(Vector2f(32*x,32*y));
		}
	}
	//
    while (window.isOpen()){
        Event event;
        while (window.pollEvent(event))
        {
            if (event.type == Event::Closed)
                window.close();
        }

        window.clear();
        window.display();
    }
    return 0;
}
Being unable to load a file into a texture shouldn't cause that to happen. It should merely fail and pop up an error message in your console (assuming you have your console open).
Since window isn't defined in main I assume that it is a global object. Since SFML depends on the order of construction of globally declared SFML objects (specifically that the ones defined by the library are constructed before yours) and since you cannot control the order of initialization, it isn't advisable for you to make such objects global.
closed account (EhqpDjzh)
I don't believe it, it was an issue with the libraries. It appears when you attempt to load a texture and it crashes like so, it's an issue with the library.

http://stackoverflow.com/questions/21131393/sfml-error-loadfromfile
Topic archived. No new replies allowed.