SFML community forums

Help => Graphics => Topic started by: Tresky on April 12, 2012, 09:01:23 pm

Title: Deleting Images
Post by: Tresky on April 12, 2012, 09:01:23 pm
Hey.
I have a for loop that creates an sf::Image* every time it loops. I want to put those sf::Image*'s into a vector and delete them to free up memory, for I wouldn't be able to access them for deletion later. I understand the sf::Sprite needs the source image around when I stick it in another vector which it why I want to keep the sf::Image*'s in a vector, but the sf::Image*'s lose there data when I copy them into the vector. A white screen is displayed where the image is supposed to be.
Is there a way to safely transfer the images and sprites into vectors?
Title: Re: Deleting Images
Post by: Digital on April 13, 2012, 12:18:07 am
Storing a pointer in a vector doesn't affect what the pointer points to. Did you create the sf::Image on the heap using new within the loop?
Title: Re: Deleting Images
Post by: eXpl0it3r on April 13, 2012, 11:39:53 am
I'd advise to learn more about C++(11) and the STL.
Then you would hopefully learn that one should not use 'raw' pointers but smart pointers, like std::shared_ptr or std::unique_ptr

For you problem, you have to allocate the resource with the new keyword otherwise the memory will get allocated on the stack and would be released as soon as you go into the next for loop iteration.

std::vector<sf::Image*> images;
for(unsigned int i=0; i < 10; ++i)
{
   sf::Image* temp = new sf::Image();
   temp.LoadFromFile("image.png");
   images.push_back(temp);
}

for(unsigned int i=0; i < images.size(); ++i)
   delete image.at(i);
 

I'd also suggest not to use SFML 1.6 anymore, mainly because it won't run on most of the computers with ATI graphic cards.
And if you switch to SFML 2 you could then also use the Thor library (https://github.com/Bromeon/Thor) for resource management, although the API will change in the near future.
Title: Re: Deleting Images
Post by: mateandmetal on April 13, 2012, 12:46:58 pm
std::vector<sf::Image*> images;
for(unsigned int i=0; i < 10; ++i)
{
   sf::Image* temp = new sf::Image();
   temp.LoadFromFile("image.png");
   images.push_back(temp);
}

for(unsigned int i=0; i < images.size(); ++i)
   delete image.at(i);
 


I would prefer doing it this way:
std::vector<sf::Image*> images;

for (unsigned int i=0; i < 10; ++i) {

   images.push_back (new sf::Image());
   images.back()->loadFromFile ("image.png");

}
 

make shure your vector doesn´t go off scope
Title: Re: Deleting Images
Post by: eXpl0it3r on April 13, 2012, 02:34:42 pm
Oh right, didn't like the temp variable too but didn't take my time to think about it longer. ;D
Title: Re: Deleting Images
Post by: Nexus on April 13, 2012, 04:54:09 pm
Then you would hopefully learn that one should not use 'raw' pointers but smart pointers, like std::shared_ptr or std::unique_ptr
I wouldn't generalize that. Usually, the preferred option should consist of directly using RAII objects, such as sf::Image. Especially std::shared_ptr has some overhead that is only worth the cost if ownership is actually shared.

Here, one could also take std::vector<sf::Image> (with reserve() to prevent reallocation) or another container.


For you problem, you have to allocate the resource with the new keyword otherwise the memory will get allocated on the stack and would be released as soon as you go into the next for loop iteration.
That's only true for the local object in the loop, but you can copy or move it into the vector or even directly construct it there (emplace it).


And if you switch to SFML 2 you could then also use the Thor library (https://github.com/Bromeon/Thor) for resource management, although the API will change in the near future.
The biggest changes have already been applied, left to do is mostly an additional all-in-one manager and some renamings.

By the way, thanks for recommending Thor all the time :)
Title: Re: Deleting Images
Post by: eXpl0it3r on April 14, 2012, 12:58:43 pm
I wouldn't generalize that. Usually, the preferred option should consist of directly using RAII objects, such as sf::Image. Especially std::shared_ptr has some overhead that is only worth the cost if ownership is actually shared.
Sure one can not generalize this, I just wanted to point him into a modern direction.

That's only true for the local object in the loop, but you can copy or move it into the vector or even directly construct it there (emplace it).
And day after day I notice, I know nothing about C++(11). :D

By the way, thanks for recommending Thor all the time :)
Hehe no problem! Great stuff should be shared! ;)

Btw congrats to your 2000th post! xD