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

Author Topic: Large arrays of sprites crashing  (Read 3861 times)

0 Members and 1 Guest are viewing this topic.

m33pn8r

  • Newbie
  • *
  • Posts: 5
    • View Profile
Large arrays of sprites crashing
« on: July 29, 2014, 02:41:22 pm »
While playing with multidimensional arrays of sprites, I began having unexpected crashing. After poking at it for a bit, I discovered that having an array of sprites over 7000 or so crashes my program immediately. Oddly, this behavior is completely reproducible on another machine, but the number of sprites required to crash is a few hundred higher.

The sprites are empty, with no data assigned.

With high working values, I see that this code is only taking about 25MB of ram, so I can't figure why I'm having issues.

SFML Version is the "GCC 4.7 MinGW (DW2) - 32 bits" version of SFML 2.1, latest stable.

I just noticed that my compiler version is GCC 4.8.1 rather than 4.7. Could this be the issue?

EDIT: Just rolled back to 4.7.2, and it's not the issue.
Also forgot to give my OS. Oops...

OS: Windows 7 S1 Professional 64-bit

I'll see if I can try to recreate on linux here in a bit.

The code to produce is the following:

int main(){

        sf::RenderWindow window(sf::VideoMode(200, 200), "Test");
        sf::Texture textures[10];

        sf::Sprite sprites[7200]; //setting this to 7100 still runs
        sprites[0].setTexture(textures[0]);

        while (window.isOpen()){
                sf::Event event;

                while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }

                window.clear();
                window.draw(sprites[0]);
                window.display();
        }

        return 0;
}
« Last Edit: July 29, 2014, 02:56:48 pm by m33pn8r »

G.

  • Hero Member
  • *****
  • Posts: 1590
    • View Profile
Re: Large arrays of sprites crashing
« Reply #1 on: July 29, 2014, 03:00:49 pm »
The stack has a (very) limited memory size.

m33pn8r

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Large arrays of sprites crashing
« Reply #2 on: July 29, 2014, 03:06:44 pm »
The stack has a (very) limited memory size.

Is that a limitation of SFML, or simply a limit of C++?

It's been a while since I've done much C++ work.

Strelok

  • Full Member
  • ***
  • Posts: 139
    • View Profile
    • GitHub
Re: Large arrays of sprites crashing
« Reply #3 on: July 29, 2014, 03:20:09 pm »
Use std::vector and forget about raw arrays.

select_this

  • Full Member
  • ***
  • Posts: 130
  • Current mood: just ate a pinecone
    • View Profile
    • darrenferrie.com
Re: Large arrays of sprites crashing
« Reply #4 on: July 29, 2014, 03:42:32 pm »
Is that a limitation of SFML, or simply a limit of C++?

It's a limitation of your CPU at the very lowest level, but your runtime environment and / or compiler can also set limits.
« Last Edit: July 29, 2014, 03:45:41 pm by select_this »
Follow me on Twitter, why don'tcha? @select_this

janszy

  • Newbie
  • *
  • Posts: 14
    • View Profile
    • Email
Re: Large arrays of sprites crashing
« Reply #5 on: July 29, 2014, 03:45:03 pm »
Use std::vector and forget about raw arrays.

Strelok is right. Use vector and extend dynamically when it's needed. Consider also reserve rather then resize (members of vector). The former only allocate memory while the latter also call the default constructor of your stored objects (which is sf::Sprite now), this cause unnecessary overhead in most cases.

Where do you load your textures btw? Doesn't setTexture throw exception when texture size is 0x0?

m33pn8r

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Large arrays of sprites crashing
« Reply #6 on: July 29, 2014, 03:51:33 pm »
I'd use vector, but I was actually using a multidimensional array originally for basing coordinates off of. I could write a struct wrapper with coords and a sprite, and put that in the vector, but I'd rather keep it simple.

After looking at my code a bit more, I won't actually be needing a full 7000+ sprites at any time, so I can work just fine within the limitations. Raising the stack size in MinGW did fix the issue though.

m33pn8r

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Large arrays of sprites crashing
« Reply #7 on: July 29, 2014, 03:53:00 pm »
Where do you load your textures btw? Doesn't setTexture throw exception when texture size is 0x0?

I wasn't getting any exceptions, but I do have a texture loader, just didn't need it in my example.

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: Large arrays of sprites crashing
« Reply #8 on: July 29, 2014, 03:57:10 pm »
I'd use vector, but I was actually using a multidimensional array originally for basing coordinates off of.

If you insist on multidimensional arrays.....

std::vector<std::vector<FooBar>> m_array;
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

janszy

  • Newbie
  • *
  • Posts: 14
    • View Profile
    • Email
Re: Large arrays of sprites crashing
« Reply #9 on: July 29, 2014, 04:01:36 pm »
You can also use vector as multidimensional:
/*
This code creates a 10x20 vector of sprites. You can index it as you would index
an array: window.draw(twoDimVec[3][6]);
Note that you have to create the inner vectors (second dimension) with a for loop.
(I'm not aware of easier solutions for that).
*/


//You must put a space between the two >> if you don't use C++11
std::vecotr<std::vector<sf::Sprite>> twoDimVec(10);
for(int i=0; i<10; ++i)
{
    twoDimVec[i] = std::vector<sf::Sprite>(20);
}

Peteck

  • Jr. Member
  • **
  • Posts: 55
    • View Profile
Re: Large arrays of sprites crashing
« Reply #10 on: July 29, 2014, 05:57:23 pm »
for(int i=0; i<10; ++i)
{
    twoDimVec[i] = std::vector<sf::Sprite>(20);
}
And to make it even more simple, use "std::fill"
std::vector<std::vector<sf::Sprite>> twoDimVec(10);
std::fill(twoDimVec.begin(), twoDimVec.begin()+10, std::vector<sf::Sprite>(20));