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

Author Topic: vector<sf::thread *> = memory leak  (Read 6644 times)

0 Members and 1 Guest are viewing this topic.

Romex

  • Newbie
  • *
  • Posts: 11
    • View Profile
vector<sf::thread *> = memory leak
« on: May 19, 2012, 12:50:58 pm »
Hello!
I use SFML 2.0 RC (17.05.2012).
This program opens new subwindow when main window is clicked.
#include<SFML\Graphics.hpp>
#include <vector>
#include<iostream>
#include <Windows.h>
std::vector < std::pair< sf::Thread * , int> > threadArray;
void loop( int id)
{
        //empty window
        sf::RenderWindow window(sf::VideoMode(800, 400, 32), "", 4);
        while ( window.isOpen() )
        {
                sf::Event event;
                while (window.pollEvent(event))
                {
                        if ((event.type == sf::Event::Closed) ||
                                ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape)))
                        {
                                window.close();
                                break;
                        }
                }
                window.clear(sf::Color::White);
                window.display();
        }
        //mark thread as ended
        for( int i=0; i<threadArray.size(); i++ )
        {
                if(threadArray[i].second == id)
                        threadArray[i].second = -1;
        }
};
int main()
{
        sf::RenderWindow window( sf::VideoMode(800, 400, 32), "memory leak example", 4);
        window.setPosition(sf::Vector2i( 0,0) );
        int threadId = 0;
        while ( window.isOpen() )
        {
                sf::Event event;
                while (window.pollEvent(event))
                {
                        if ((event.type == sf::Event::Closed) ||
                                ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape)))
                        {
                                window.close();
                                break;
                        }
                        if(event.type == event.MouseButtonPressed)
                        {
                                if(event.mouseButton.button == sf::Mouse::Left)
                                {
                                        int i=0;
                                        //use ended
                                        for(; i < threadArray.size(); i++)
                                        {
                                                if( threadArray[i].second == -1 )
                                                {
                                                        threadArray[i].first->launch();
                                                        threadArray[i].second = i;
                                                        break;
                                                }
                                        }
                                        //or create new thread
                                        if( i== threadArray.size() )
                                        {
                                                threadArray.push_back( std::pair< sf::Thread* , int >( new sf::Thread( &loop, threadId ), threadId ) );
                                                threadArray.back().first->launch();
                                                Sleep(100);
                                                threadId++;
                                        }
                                }
                        }
                }
                window.clear(sf::Color::White);
                window.display();
        }
        return EXIT_SUCCESS;
}
 
It works, but I noticed memory leak about 3mb per new subwindow.
I suppose it's incorrect to store threads in dynamic memory, but I have not any idea how to do it differently.
How can I solve this problem?
Thank you for your help and sorry for my English.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: vector<sf::thread *> = memory leak
« Reply #1 on: May 19, 2012, 01:05:39 pm »
You use new but no delete and wonder about memory leaks?

Normally I'd suggest to store sf::Thread instead of sf::Thread*, but here that is problematic because the thread class is noncopyable and has no move semantics. If your compiler supports C++11, use std::unique_ptr<sf::Thread>.
« Last Edit: May 19, 2012, 01:10:13 pm by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Romex

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: vector<sf::thread *> = memory leak
« Reply #2 on: May 19, 2012, 01:12:08 pm »
I don't use delete because it's not necessary. Ended threads are used again.
thread class is noncopyable and has no move semantics. [/tt].
It's main problem.
« Last Edit: May 19, 2012, 01:13:48 pm by Romex »

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: vector<sf::thread *> = memory leak
« Reply #3 on: May 19, 2012, 01:18:15 pm »
I don't use delete because it's not necessary.
Of course it's necessary, every new requires a delete. In case of smart pointers, this is just automated.

Ended threads are used again.
That changes nothing. Eventually, the memory must be deallocated.

But you're doing it very complicated anyway. Why don't you write a class that stores a window and its own thread? Then you can just have a container with elements of this class, and don't need questionable code to reuse threads.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Romex

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: vector<sf::thread *> = memory leak
« Reply #4 on: May 19, 2012, 01:35:51 pm »
#include<SFML\Graphics.hpp>
#include <vector>
#include<iostream>
#include <Windows.h>
std::vector < std::pair< sf::Thread * , int> > threadArray;
void loop( int id)
{
        //empty window
        sf::RenderWindow window(sf::VideoMode(800, 400, 32), "", 4);
        while ( window.isOpen() )
        {
                sf::Event event;
                while (window.pollEvent(event))
                {
                        if ((event.type == sf::Event::Closed) ||
                                ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape)))
                        {
                                window.close();
                                break;
                        }
                }
                window.clear(sf::Color::White);
                window.display();
        }
        //mark thread as ended
        for( int i=0; i<threadArray.size(); i++ )
        {
                if(threadArray[i].second == id)
                        threadArray[i].second = -1;
        }
};
int main()
{
        sf::RenderWindow window( sf::VideoMode(800, 400, 32), "memory leak example", 4);
        window.setPosition(sf::Vector2i( 0,0) );
        int threadId = 0;
        while ( window.isOpen() )
        {
                sf::Event event;
                while (window.pollEvent(event))
                {
                        if ((event.type == sf::Event::Closed) ||
                                ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape)))
                        {
                                window.close();
                                break;
                        }
                        if(event.type == event.MouseButtonPressed)
                        {
                                if(event.mouseButton.button == sf::Mouse::Left)
                                {

                                        threadArray.push_back( std::pair< sf::Thread* , int >( new sf::Thread( &loop, threadId ), threadId ) );
                                        threadArray.back().first->launch();
                                        Sleep(100);
                                        threadId++;
                                }
                        }
                }
                for( int i=0; i < threadArray.size(); i++ )
                {
                        if(threadArray[i].second == -1)
                        {
                                delete threadArray[i].first;
                                threadArray.erase( threadArray.begin() + i );
                                i = 0;
                        }
                }
                window.clear(sf::Color::White);
                window.display();
        }
        return EXIT_SUCCESS;
}


 
This code with regular deallocating without using ended threads has the same problem.
Quote
Why don't you write a class that stores a window and its own thread? Then you can just have a container with elements of this class, and don't need questionable code to reuse threads.
It's not that code where I noticed the problem.
I tried to write simple example which illustrate trouble. Sorry if it is not good.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: vector<sf::thread *> = memory leak
« Reply #5 on: May 19, 2012, 01:41:05 pm »
Are you sure there's a memory leak (and not just the allocation in the Windows Task Manager)? How did you measure it?
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Romex

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: vector<sf::thread *> = memory leak
« Reply #6 on: May 19, 2012, 01:51:05 pm »
Are you sure there's a memory leak (and not just the allocation in the Windows Task Manager)? How did you measure it?
Yes, I am. Intel Parallel Studio.

Romex

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: vector<sf::thread *> = memory leak
« Reply #7 on: May 19, 2012, 03:08:18 pm »
Problem is solved!
Program I used finds leaks in code without SFML.
Sorry for claiming :'(

 

anything