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

Author Topic: Memory Management by loadfrommemory  (Read 8471 times)

0 Members and 1 Guest are viewing this topic.

etixpp

  • Jr. Member
  • **
  • Posts: 82
    • View Profile
    • FoxFire Development Website
    • Email
Memory Management by loadfrommemory
« on: November 06, 2013, 10:13:12 pm »
Hello.
I got a small problem and i am kind of clueless about this because it should normally not be possible,
I have a chunk class which contains 3 textures and 3 sprites.
On chunk.update() i load the files from my website and put then into the texture like this
                                sf::Http http;
                                http.setHost("http://bla.de/");
                                sf::Http::Request request;
                                request.setMethod(sf::Http::Request::Get);
                                request.setUri("images/"+Bg);
                                request.setHttpVersion(1, 1); // HTTP 1.1
                                sf::Http::Response response = http.sendRequest(request);
                                std::string body = response.getBody();

                                BgTexture.loadFromMemory(body.data(),body.size());
                                BgSprite.setTexture(BgTexture);

Now i created 4 testchunks
      
chunk Chunk1("rpgbg_0","rpggraphics_0","rpgcolli_0",1);
                chunk Chunk2("rpgbg_0","rpggraphics_0","rpgcolli_0",2);
                chunk Chunk3("rpgbg_0","rpggraphics_0","rpgcolli_0",3);
                chunk Chunk4("rpgbg_0","rpggraphics_0","rpgcolli_0",4);


And i have a pointer which allways points to the chunk, which has to be drawn:
chunk* MainChunk = &Chunk1;

Everything nice so far, i switch stuff with hotkeys

                                if ( AreaSwapClock.getElapsedTime().asSeconds() > 1.F)
                                {
                                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Num1))
                                {
                                        OldMainChunk = MainChunk;
                                        MainChunk = &Chunk1;
                                        std::cout << "test";
                                        ChunkRenderThread.launch();
                                        AreaSwapClock.restart();
                                }
                                }
And everything works. Pls do not ask why i do it how i do it, it´s necesary.
Anyways the update happens in a thread , which does this function and closes

void RenderChunks()
{
        loadscreen = true;
        MainChunk->update();
        std::cout << "thread"<< std::endl;
        loadscreen = false;

}




Well now the problem:
As more i switch the area as more memory gets allocated , obviously this happens but now what makes me really sick atm:
I tried a LOT of methods to stop this, at example i have put all chunk´s in a vector and if i change a chunk i first clear the vector, set him up from new and then update the chunk, so the old chunk objekt MUST be deleted and the memory goes free.
Well the ram did not care and as more i switched areas as more got allocated.

Then i tried to make a terminate function and filled the textures and spirtes with a clear dummy sprite and texture, so they take MINIMAL memory.
Well the memory usage was again going higher as more i swap and did not care.

I even tried to call manually destructors for the stuff, which i should not do, just fore testing, nothing changed.
The only possible way i see is that something with    MainTexture.loadFromMemory(body.data(),body.size()); goes in Sfml wrong and the used memory never gets deleted, even if the object which should contain it does not exist anymore.
Or do you have a other explanation?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Memory Management by loadfrommemory
« Reply #1 on: November 06, 2013, 10:22:55 pm »
You should write a complete and minimal example that reproduces the problem. There are so many things that could cause a memory leak in a complete application...
Laurent Gomila - SFML developer

etixpp

  • Jr. Member
  • **
  • Posts: 82
    • View Profile
    • FoxFire Development Website
    • Email
Re: Memory Management by loadfrommemory
« Reply #2 on: November 08, 2013, 06:41:10 pm »
Sry, no time atm to make a example, i fixed it on another way, but maybe you should check this because i am pretty sure, there is going something in a wrong way.
Just make a webrequest, pull a image from a website and initialize a texture with body.data and size, if you change or load again the same stuff on the same texture, it will become bigger and bigger if you use loadfrommemory .
One way to fix this would probably be to create a new local texture, load it to the new texture and overwrite the old static texture with copy constructor to the local texture which get´s deleted after leaving scope.
I just load all recources one time at game start for every chunk now and do not update on working game. Take few seconds to load at start´s but shall be no probably with a nice launcher *lol*

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Memory Management by loadfrommemory
« Reply #3 on: November 09, 2013, 12:43:56 pm »
Sry, no time atm to make a example [...] but maybe you should check this because i am pretty sure, there is going something in a wrong way.
There are a lot of people reporting alleged memory leaks. Most of the cases, they are reported because:
  • People don't know about RAII and have memory leaks in their own code
  • Memory leaks are not actually observed, but guessed ("the RAM usage of my application goes up")
  • Tools such as valgrind are used incorrectly, most often related to objects with static storage
Unless there is other evidence, we believe this to be the case here, too.

Without a minimal and complete example, your description doesn't really help us. We have to make sure we reproduce the same conditions that you have. So if you are truly interested in a fix of the problem, take the time to write down a corresponding code. If it can be done with the steps you mentioned, that shouldn't take long after all.
« Last Edit: November 09, 2013, 12:46:43 pm by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

etixpp

  • Jr. Member
  • **
  • Posts: 82
    • View Profile
    • FoxFire Development Website
    • Email
Re: Memory Management by loadfrommemory
« Reply #4 on: November 09, 2013, 05:15:31 pm »
i already fixed this now, the behaviour of the program was undefined anyways due to using a wrong version sfgui.dll , which worked but some crazy things happened.

I created a example and saw that the stuff worked properly so i checked my code again and again and when i changed linking and mode to debug it worked so i got aware of wrong release sfgui dll.

etixpp

  • Jr. Member
  • **
  • Posts: 82
    • View Profile
    • FoxFire Development Website
    • Email
Re: Memory Management by loadfrommemory
« Reply #5 on: November 11, 2013, 11:00:16 pm »
Ok i got a little bit more into this and i am at a point where i just can´t understand the behavior anymore, it´s about threads which is a bit complexe for sure, but i always used threads and had no problems, but atm i have watched this phenomen:
See i have a Area switch and a koord system of areas, when i switch now this function updates the actual point at the coord system, the problem is now: If i do not use threads the memory is just fine, everything goes it´s way and it keeps arround 42k.
Now i go for threads, because while the texture is updating, it take 2-3 Seconds and i would like to make some loadscreen in the mainloop, so i put the function in a thread, set some bool which makes sure the thread doesnt get launched twice if i am at a border and added a loadscreen bool, so the mainfunction does no other stuff while thread is running.
It works perfectly BUT the allocated memory gets higher and higher, no matter what i do, it can go to 8 gb ram allocation if i let it run for the whole night *lol*
So i thought, ok laurent said in discription sf::Thread is a big bag of crap so i used std::thread and had the same, even stronger experience.

What i do normally without thrad and what does no memory leak:
MainMap.UpdateMap(MainPlayer,Chunk1,MainView);

What i do now with thread:
            
               
                if(MainMap.UpdateMap(MainPlayer,Chunk1,MainView,1))
                                {

                                        loadscreen = true;                     
                                        if(SwapThreadRunning == false)
                                        {

                                        MapColliChecker.launch();
                                        std::cout << "test;";
                                        }
                                       
                       
                                }
               
                                }

Thread function:

void RenderChunks()
{
        loadscreen = true;
        ChunkPointer->update();
        loadscreen = false;
}


Just to let u know, the overloaded function of update map with 1 at the end checks if i am at a border, if i wouldnt do this the framerate would nock down, because nonstop check in thread is too hard and its ok if its checked on every frame, without the ,1 it goes directly for one check if i am at border and switches instantly.
So only if i am realy at Border it starts the Thread which swaps the area.

All in all this 2 methods do EXACTLY the same, ony difference is that the one works with thread.
« Last Edit: November 11, 2013, 11:02:53 pm by etixpp »

wintertime

  • Sr. Member
  • ****
  • Posts: 255
    • View Profile
Re: Memory Management by loadfrommemory
« Reply #6 on: November 11, 2013, 11:50:11 pm »
Looks like you possibly created a race condition. If you can avoid it you better do not use threads.
You can not just use some global variables for communicating between threads; they have to be protected by a critical section and then you need to carefully check all combinations of all substeps of all running threads what can happen there and if that would be wrong.

etixpp

  • Jr. Member
  • **
  • Posts: 82
    • View Profile
    • FoxFire Development Website
    • Email
Re: Memory Management by loadfrommemory
« Reply #7 on: November 12, 2013, 01:05:24 pm »
It´s only one running thread, this shoudln´t be too complicated at all...

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10911
    • View Profile
    • development blog
    • Email
Re: Memory Management by loadfrommemory
« Reply #8 on: November 12, 2013, 01:35:48 pm »
You can use std::atomic<bool> or std::atomic_bool (typedef) to remove the race condition on the boolean variable, but you'll need that C++11 feature (see reference).

Where the allocation is happening is another issue though, can you create a minimal example that reproduces the issue?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

etixpp

  • Jr. Member
  • **
  • Posts: 82
    • View Profile
    • FoxFire Development Website
    • Email
Re: Memory Management by loadfrommemory
« Reply #9 on: November 12, 2013, 05:01:41 pm »
Example:
Version 1 without thread:
On F5 i go to arround 38,5 k. Ofc while its working on f5 it goes up a bit but cools down on exact the old number after job is done:
#include <SFML\Graphics.hpp>
#include <SFML\Network.hpp>
#include <iostream>
void gogo()
{
        std::cout << "running" << std::endl;

}
int main()
{
    sf::RenderWindow  window(sf::VideoMode(800, 600), "My window");
        sf::Texture BgTexture;
        sf::Sprite BgSprite;
    // run the program as long as the window is open
    while (window.isOpen())
    {
                                                        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Num5))
                                                        {
                                                        {              
                                                                sf::Http http;
                                                                http.setHost("http://riedbook.de/");
                                                                sf::Http::Request request;
                                                                request.setMethod(sf::Http::Request::Get);
                                                                request.setUri("images/rpgbg_x1_y1.png");
                                                                request.setHttpVersion(1, 1); // HTTP 1.1
                                                                sf::Http::Response response = http.sendRequest(request);
                                                                std::string body = response.getBody();
                                                                sf::Texture changeTex;
               
                                                                changeTex.loadFromMemory(body.data(),body.size());
                                                                BgTexture = changeTex;
                                                                BgSprite.setTexture(BgTexture);
                                                        }              
                                                        {
                                                                sf::Http http;
                                                                http.setHost("http://riedbook.de/");
                                                                sf::Http::Request request;
                                                                request.setMethod(sf::Http::Request::Get);
                                                                request.setUri("images/rpgbg_x1_y1.png");
                                                                request.setHttpVersion(1, 1); // HTTP 1.1
                                                                sf::Http::Response response = http.sendRequest(request);
                                                                std::string body = response.getBody();
                                                                sf::Texture changeTex;
               
                                                                changeTex.loadFromMemory(body.data(),body.size());
                                                                BgTexture = changeTex;
                                                                BgSprite.setTexture(BgTexture);
                                                        }
                                                        }

        // check all the window's events that were triggered since the last iteration of the loop
        sf::Event event;
        while (window.pollEvent(event))
        {
            // "close requested" event: we close the window
            if (event.type == sf::Event::Closed)
                window.close();
        }
                window.draw(BgSprite);
                window.display();
    }

    return 0;
}


 



Version 2:
Now we do the same stuff with a thread. i can see: first 30, then after then after doing it again 31, 32, 33,34 and so on, i continiued to 100k, i am sure i could do it to Ram overload.

#include <SFML\Graphics.hpp>
#include <SFML\Network.hpp>
#include <iostream>
sf::Texture BgTexture;
sf::Sprite BgSprite;
void gogo()
{
                {              
                        sf::Http http;
                        http.setHost("http://riedbook.de/");
                        sf::Http::Request request;
                        request.setMethod(sf::Http::Request::Get);
                        request.setUri("images/rpgbg_x1_y1.png");
                        request.setHttpVersion(1, 1); // HTTP 1.1
                        sf::Http::Response response = http.sendRequest(request);
                        std::string body = response.getBody();
                        sf::Texture changeTex;
               
                        changeTex.loadFromMemory(body.data(),body.size());
                        BgTexture = changeTex;
                        BgSprite.setTexture(BgTexture);
                }              
                {
                        sf::Http http;
                        http.setHost("http://riedbook.de/");
                        sf::Http::Request request;
                        request.setMethod(sf::Http::Request::Get);
                        request.setUri("images/rpgbg_x1_y1.png");
                        request.setHttpVersion(1, 1); // HTTP 1.1
                        sf::Http::Response response = http.sendRequest(request);
                        std::string body = response.getBody();
                        sf::Texture changeTex;
               
                        changeTex.loadFromMemory(body.data(),body.size());
                        BgTexture = changeTex;
                        BgSprite.setTexture(BgTexture);
                }

}
int main()
{
    sf::RenderWindow  window(sf::VideoMode(800, 600), "My window");
        sf::Thread RenderThread(gogo);
    // run the program as long as the window is open
    while (window.isOpen())
    {
                                                        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Num5))
                                                        {
                                                                RenderThread.launch();
                                                        }

        // check all the window's events that were triggered since the last iteration of the loop
        sf::Event event;
        while (window.pollEvent(event))
        {
            // "close requested" event: we close the window
            if (event.type == sf::Event::Closed)
                window.close();
        }
                window.draw(BgSprite);
                window.display();
    }

    return 0;
}


 

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10911
    • View Profile
    • development blog
    • Email
Re: Memory Management by loadfrommemory
« Reply #10 on: November 12, 2013, 05:59:19 pm »
There are a few mistakes which may or may not have anything to do with the issue at hand.

  • You should always use forward slashes for path, i.e. <SFML/Graphics.hpp>.
  • SFML resources should never be in the global scope, it's anyways recommended to avoid global variables. The destruction order of global variables is not defined, thus it can lead to issues.
  • You have a race condition on the sprite and texture, since you're changing the sprite in one thread and reading it on the main thread. You should make sure that shared objects are either only being read by multiple threads or protect it (e.g. with a mutex or reader-writer-lock) when writing in one and reading in another thread.
  • You're calling launch() multiple times. I'm not sure if SFML allows that, but it's probably not what you've intended. If the launched thread processes fast enough, you might even run everything multiple times. That is because you're only doing a isKeyPressed check in the while loop and since the loop is not limited it will run at full speed. So if you'd get an FPS of 2000 and then you can't hold the key longer than 1/2000 s otherwise you'll enter the if-block again.

So it shows again that you might want to learn a lot more on parallel programming, it's an advanced topic. ;)

Have you actually seen the memory usage go over say 1GiB or were those all estimates from a few kilobytes changes? Where did you watch the growth, because the task manager is not the best place, unless the growth is obvious.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

etixpp

  • Jr. Member
  • **
  • Posts: 82
    • View Profile
    • FoxFire Development Website
    • Email
Re: Memory Management by loadfrommemory
« Reply #11 on: November 12, 2013, 06:25:19 pm »
I watched a growth over 1 gb more Ram, this is pretty obvious.

Quote
You should always use forward slashes for path, i.e. <SFML/Graphics.hpp>.

I will do this in future but there is now way this could affect the problem.

Quote
SFML resources should never be in the global scope, it's anyways recommended to avoid global variables. The destruction order of global variables is not defined, thus it can lead to issues.
They must, otherwise the thread is not able to access them. I am absolutly no friend of global shit, but it´s needed since scope´s are scopes *lol* i even asked about this http://en.sfml-dev.org/forums/index.php?topic=13499.0 because i was not sure about the formulation in the recources example.

You have a race condition on the sprite and texture, since you're changing the sprite in one thread and reading it on the main thread. You should make sure that shared objects are either only being read by multiple threads or protect it (e.g. with a mutex or reader-writer-lock) when writing in one and reading in another thread.

I will try this and give report as soon as possible

Quote
You're calling launch() multiple times. I'm not sure if SFML allows that, but it's probably not what you've intended. If the launched thread processes fast enough, you might even run everything multiple times. That is because you're only doing a isKeyPressed check in the while loop and since the loop is not limited it will run at full speed. So if you'd get an FPS of 2000 and then you can't hold the key longer than 1/2000 s otherwise you'll enter the if-block again.
This is a mistake in my example script of course. I normally use a sf::clock check for this, but it changes nothing anyways.

i updated it, was kinda fast, maybe still a mistake, but i am watching the same phenomen:

#include <SFML\Graphics.hpp>
#include <SFML\Network.hpp>
#include <iostream>
sf::Texture BgTexture;
sf::Sprite BgSprite;
bool nstuffrunning;
void gogo()
{
                {              
                        sf::Http http;
                        http.setHost("http://riedbook.de/");
                        sf::Http::Request request;
                        request.setMethod(sf::Http::Request::Get);
                        request.setUri("images/rpgbg_x1_y1.png");
                        request.setHttpVersion(1, 1); // HTTP 1.1
                        sf::Http::Response response = http.sendRequest(request);
                        std::string body = response.getBody();
                        sf::Texture changeTex;
               
                        changeTex.loadFromMemory(body.data(),body.size());
                        BgTexture = changeTex;
                        BgSprite.setTexture(BgTexture);
                }              
                {
                        sf::Http http;
                        http.setHost("http://riedbook.de/");
                        sf::Http::Request request;
                        request.setMethod(sf::Http::Request::Get);
                        request.setUri("images/rpgbg_x1_y1.png");
                        request.setHttpVersion(1, 1); // HTTP 1.1
                        sf::Http::Response response = http.sendRequest(request);
                        std::string body = response.getBody();
                        sf::Texture changeTex;
               
                        changeTex.loadFromMemory(body.data(),body.size());
                        BgTexture = changeTex;
                        BgSprite.setTexture(BgTexture);
                }
                nstuffrunning = false;


}
int main()
{
        sf::Clock clock;
        nstuffrunning = false;
    sf::RenderWindow  window(sf::VideoMode(800, 600), "My window");
        sf::Thread RenderThread(gogo);
    // run the program as long as the window is open
    while (window.isOpen())
    {
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Num5) && clock.getElapsedTime().asSeconds() > 4)
                {
                        nstuffrunning = true;
                        RenderThread.launch();
                        clock.restart();
                }

        // check all the window's events that were triggered since the last iteration of the loop
        sf::Event event;
        while (window.pollEvent(event))
        {
            // "close requested" event: we close the window
            if (event.type == sf::Event::Closed)
                window.close();
        }
                if (!nstuffrunning)
                window.draw(BgSprite);
                window.display();
    }

    return 0;
}

 



I will try mutex, or at least i tried it before a weak and had the same problem, could you show me a example on the example script, how you would use mutex to prevent this?

I just created a sf::Mutex mutex; at top and locked it in main and in the thread before the start and opened it after stuff done




EDIT:

Well ok there is a way to solve it without globals (just did not think about it enough*lol*), but afaik the problem keeps beeing the same. Only the bool is global now, but it can´t be about the bool, a bool variable takes 1 byte, it must be about the textures
#include <SFML\Graphics.hpp>
#include <SFML\Network.hpp>
#include <iostream>
bool nstuffrunning;
class test
{
private:
        sf::Texture* BgTexture;
        sf::Sprite* BgSprite;
public:
        test(sf::Texture* pBg,sf::Sprite* pSpr )
        {
                BgTexture = pBg;
                BgSprite = pSpr;
        }
        void gogo()
{
                {              
                        sf::Http http;
                        http.setHost("http://riedbook.de/");
                        sf::Http::Request request;
                        request.setMethod(sf::Http::Request::Get);
                        request.setUri("images/rpgbg_x1_y1.png");
                        request.setHttpVersion(1, 1); // HTTP 1.1
                        sf::Http::Response response = http.sendRequest(request);
                        std::string body = response.getBody();
                        sf::Texture changeTex;
               
                        BgTexture->loadFromMemory(body.data(),body.size());
                        BgSprite->setTexture(*BgTexture);
                }              
                {
                        sf::Http http;
                        http.setHost("http://riedbook.de/");
                        sf::Http::Request request;
                        request.setMethod(sf::Http::Request::Get);
                        request.setUri("images/rpgbg_x1_y1.png");
                        request.setHttpVersion(1, 1); // HTTP 1.1
                        sf::Http::Response response = http.sendRequest(request);
                        std::string body = response.getBody();
                        sf::Texture changeTex;
               
                        BgTexture->loadFromMemory(body.data(),body.size());
                        BgSprite->setTexture(*BgTexture);
                }
                nstuffrunning = false;


}
};

int main()
{
        sf::Texture BgTexture;
        sf::Sprite BgSprite;
        sf::Texture* pointer1 = &BgTexture ;
        sf::Sprite* pointer2 = &BgSprite ;
        test funcclass ( pointer1,pointer2) ;
        sf::Clock clock;
        nstuffrunning = false;
    sf::RenderWindow  window(sf::VideoMode(800, 600), "My window");
        sf::Thread RenderThread(&test::gogo,&funcclass);
    // run the program as long as the window is open
    while (window.isOpen())
    {
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Num5) && clock.getElapsedTime().asSeconds() > 4)
                {
                        nstuffrunning = true;
                        RenderThread.launch();
                        clock.restart();
                }

        // check all the window's events that were triggered since the last iteration of the loop
        sf::Event event;
        while (window.pollEvent(event))
        {
            // "close requested" event: we close the window
            if (event.type == sf::Event::Closed)
                window.close();
        }
                if (!nstuffrunning)
                window.draw(BgSprite);
                window.display();
    }

    return 0;
}

 
« Last Edit: November 12, 2013, 07:01:21 pm by etixpp »

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Memory Management by loadfrommemory
« Reply #12 on: November 12, 2013, 08:15:11 pm »
I will do this in future but there is now way this could affect the problem.
Nobody claimed that it would, but we also like to give advice apart from the problem :)

They must, otherwise the thread is not able to access them.
Of course it is. Just pass them as parameters, like you do with any other functions. Avoid global variables wherever possible. You misunderstood the answers in the other thread, of course global variables are not necessary. But you cannot just expect arbitrary scopes to interfere with each other, you have to use the language features (function parameters and return types) to communicate between them.

Only the bool is global now, but it can´t be about the bool, a bool variable takes 1 byte, it must be about the textures
This is again wrong, you should really have an in-depth look at multithreading before you use it. bool variables are, like everything else, not threadsafe. That's also the reason why exploiter suggested atomics.

So, fix this before anything else. Remove all global variables in your code. And please reduce your code to the bare minimum, nobody cares about HTTP connections and other unrelated things.
« Last Edit: November 12, 2013, 08:18:38 pm by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

etixpp

  • Jr. Member
  • **
  • Posts: 82
    • View Profile
    • FoxFire Development Website
    • Email
Re: Memory Management by loadfrommemory
« Reply #13 on: November 12, 2013, 08:32:12 pm »
I will do this in future but there is now way this could affect the problem.
Nobody claimed that it would, but we also like to give advice apart from the problem :)

They must, otherwise the thread is not able to access them.
Of course it is. Just pass them as parameters, like you do with any other functions. Avoid global variables wherever possible. You misunderstood the answers in the other thread, of course global variables are not necessary. But you cannot just expect arbitrary scopes to interfere with each other, you have to use the language features (function parameters and return types) to communicate between them.

Only the bool is global now, but it can´t be about the bool, a bool variable takes 1 byte, it must be about the textures
This is again wrong, you should really have an in-depth look at multithreading before you use it. bool variables are, like everything else, not threadsafe. That's also the reason why exploiter suggested atomics.

So, fix this before anything else. Remove all global variables in your code. And please reduce your code to the bare minimum, nobody cares about HTTP connections and other unrelated things.
If u would scroll 2 centimeters more to bottom, you would have seen that i already provided a solution without globals D: And ye i deleted all globals now, no change at all.
And the image pull is what has to get working and is anyways needed to notice the problem, otherwise it´s there but needs a lot of time to show for sure.


I know i suck, but i work since a weak every day on this problem...i tried over 9000 things x.X



I never used atomic till now so i´ve read a few lines and tried this stuff,

#include <SFML\Graphics.hpp>
#include <SFML\Network.hpp>
#include <iostream>
#include <atomic>
class test
{
private:
        sf::Texture* BgTexture;
        sf::Sprite* BgSprite;
public:
        test(sf::Texture* pBg,sf::Sprite* pSpr )
        {
                BgTexture = pBg;
                BgSprite = pSpr;

        }
        void gogo()
{
                {              
                        sf::Http http;
                        http.setHost("http://riedbook.de/");
                        sf::Http::Request request;
                        request.setMethod(sf::Http::Request::Get);
                        request.setUri("images/rpgbg_x1_y1.png");
                        request.setHttpVersion(1, 1); // HTTP 1.1
                        sf::Http::Response response = http.sendRequest(request);
                        std::string body = response.getBody();
                        sf::Texture changeTex;
               
                        BgTexture->loadFromMemory(body.data(),body.size());
                        BgSprite->setTexture(*BgTexture);
                }              
                {
                        sf::Http http;
                        http.setHost("http://riedbook.de/");
                        sf::Http::Request request;
                        request.setMethod(sf::Http::Request::Get);
                        request.setUri("images/rpgbg_x1_y1.png");
                        request.setHttpVersion(1, 1); // HTTP 1.1
                        sf::Http::Response response = http.sendRequest(request);
                        std::string body = response.getBody();
                        sf::Texture changeTex;
               
                        BgTexture->loadFromMemory(body.data(),body.size());
                        BgSprite->setTexture(*BgTexture);
                }


}
};

int main()
{
        std::atomic<sf::Texture> BgTexture;
        std::atomic<sf::Sprite> BgSprite;
        sf::Texture* pointer1 = &BgTexture.load() ;
        sf::Sprite* pointer2 = &BgSprite.load() ;

        test funcclass ( pointer1,pointer2) ;
        sf::Clock clock;
    sf::RenderWindow  window(sf::VideoMode(800, 600), "My window");
        sf::Thread RenderThread(&test::gogo,&funcclass);
    // run the program as long as the window is open
    while (window.isOpen())
    {
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Num5) && clock.getElapsedTime().asSeconds() > 4)
                {
                        RenderThread.launch();
                        clock.restart();
                }

        // check all the window's events that were triggered since the last iteration of the loop
        sf::Event event;
        while (window.pollEvent(event))
        {
            // "close requested" event: we close the window
            if (event.type == sf::Event::Closed)
                window.close();
        }
                window.draw(BgSprite);
                window.display();
    }

    return 0;
}


 

but get error which points me to this:
void __cdecl _NMSG_WRITE (
        int rterrnum
        )
{
        const wchar_t * const error_text = _GET_RTERRMSG(rterrnum);

        if (error_text)
        {
            int msgshown = 0;
#ifdef _DEBUG
            /*
             * Report error.
             *
             * If _CRT_ERROR has _CRTDBG_REPORT_WNDW on, and user chooses
             * "Retry", call the debugger.
             *
             * Otherwise, continue execution.
             *
             */


            if (rterrnum != _RT_CRNL && rterrnum != _RT_BANNER && rterrnum != _RT_CRT_NOTINIT)
            {
                switch (_CrtDbgReportW(_CRT_ERROR, NULL, 0, NULL, L"%s", error_text))
                {
                case 1: _CrtDbgBreak(); msgshown = 1; break;
                case 0: msgshown = 1; break;
                }
            }
#endif  /* _DEBUG */

Could you show me some example code to my example, which should fix the problem in your opinion? Would be really great x.X



EDIT:

i created another example which causes the same trouble ->

#include <SFML\Graphics.hpp>
#include <SFML\Network.hpp>
#include <iostream>
sf::Mutex mutex;
class test
{
private:
        sf::Texture* BgTexture;
        sf::Sprite* BgSprite;
public:
        test(sf::Texture* pBg,sf::Sprite* pSpr )
        {
                BgTexture = pBg;
                BgSprite = pSpr;

        }
        void gogo()
{
        mutex.lock();
        sf::Image test;
        test.create(500,500);
        BgTexture->loadFromImage(test);
        BgSprite->setTexture(*BgTexture);
                  mutex.unlock();

}
};

int main()
{
        sf::Texture BgTexture;
        sf::Sprite BgSprite;
        sf::Texture* pointer1 = &BgTexture ;
        sf::Sprite* pointer2 = &BgSprite ;

        test funcclass ( pointer1,pointer2) ;
        sf::Clock clock;
    sf::RenderWindow  window(sf::VideoMode(800, 600), "exa");
        sf::Thread RenderThread(&test::gogo,&funcclass);
    // run the program as long as the window is open
    while (window.isOpen())
    {
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Num5) && clock.getElapsedTime().asSeconds() > 1)
                {
                        RenderThread.launch();
                        clock.restart();
                }

        // check all the window's events that were triggered since the last iteration of the loop
        sf::Event event;
        while (window.pollEvent(event))
        {
            // "close requested" event: we close the window
            if (event.type == sf::Event::Closed)
                window.close();
        }
                mutex.lock();
                window.draw(BgSprite);
                mutex.unlock();
                window.display();
    }

    return 0;
}


 
« Last Edit: November 12, 2013, 10:21:48 pm by etixpp »

etixpp

  • Jr. Member
  • **
  • Posts: 82
    • View Profile
    • FoxFire Development Website
    • Email
Re: Memory Management by loadfrommemory
« Reply #14 on: November 13, 2013, 01:51:49 pm »
So as summary, could somebody show me on this example how i should stop this from memory leaking?

[code=cpp]#include <SFML\Graphics.hpp>
#include <SFML\Network.hpp>
#include <iostream>
sf::Mutex mutex;
class test
{
private:
        sf::Texture* BgTexture;
        sf::Sprite* BgSprite;
public:
        test(sf::Texture* pBg,sf::Sprite* pSpr )
        {
                BgTexture = pBg;
                BgSprite = pSpr;

        }
        void gogo()
{
        mutex.lock();
        sf::Image test;
        test.create(500,500);
        BgTexture->loadFromImage(test);
        BgSprite->setTexture(*BgTexture);
                  mutex.unlock();

}
};

int main()
{
        sf::Texture BgTexture;
        sf::Sprite BgSprite;
        sf::Texture* pointer1 = &BgTexture ;
        sf::Sprite* pointer2 = &BgSprite ;

        test funcclass ( pointer1,pointer2) ;
        sf::Clock clock;
    sf::RenderWindow  window(sf::VideoMode(800, 600), "exa");
        sf::Thread RenderThread(&test::gogo,&funcclass);
    // run the program as long as the window is open
    while (window.isOpen())
    {
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Num5) && clock.getElapsedTime().asSeconds() > 1)
                {
                        RenderThread.launch();
                        clock.restart();
                }

        // check all the window's events that were triggered since the last iteration of the loop
        sf::Event event;
        while (window.pollEvent(event))
        {
            // "close requested" event: we close the window
            if (event.type == sf::Event::Closed)
                window.close();
        }
                mutex.lock();
                window.draw(BgSprite);
                mutex.unlock();
                window.display();
    }

    return 0;
}


 
[/code]