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

Author Topic: SFML Draw method leaking memory?  (Read 1364 times)

0 Members and 1 Guest are viewing this topic.

PoppingNuts

  • Newbie
  • *
  • Posts: 2
    • View Profile
    • Email
SFML Draw method leaking memory?
« on: October 20, 2020, 05:16:57 am »
I'm using an entity manager which basically updates and draws my container of entities. Like so:
        void Draw(sf::RenderWindow *l_window) {
                if (m_entities.empty()) return;

                for (auto &itr : m_entities) {
                        itr.second->Draw(l_window);
                }
        }
 
I use a factory method that simply returns a pointer the the newly allocated memory:
template<typename T>
        void RegisterEntity(const EntityType &l_type) {
                m_entityFactory[l_type] = [this]() -> BaseEntity*
                {
                        return new T();
                };
        }
 
Then, I add a new entity by just emplacing the pointer to a new container:
void AddEntity(const EntityType &l_type, const std::string &l_name, sf::Vector2f l_pos = sf::Vector2f(0,0)) {
                auto itr = m_entityFactory.find(l_type);
                if (itr == m_entityFactory.end()) return;
                BaseEntity* entity = itr->second();
                entity->m_id = m_idCounter;
                if (entity->m_name == "") entity->m_name = l_name;
                m_entities.emplace(m_idCounter, entity);

                ...


                ++m_idCounter;
        }
 
Ultimately, I call the update and draw method on the main loop:
while (window.isOpen()) {
                sf::Event evnt;
                while (window.pollEvent(evnt)) {
                        if (evnt.type == sf::Event::Closed) {
                                window.close();
                        }
                        ...
                }

                ...

                ...

                window.clear(sf::Color::Black);
                entityManager.Draw(&window);
                window.display();

                time = clock.restart();
        }
 
However, the "entityManager.Draw(&window)" is causing a memory leak. It only does that when it's drawing entities, which are only sf::RectangleShape. Even when I draw only one entity that happens. Here is the Base entity classe:
class BaseEntity {
        friend class EntityManager;
protected:
        ...
        sf::RectangleShape m_sprite;
        ...
public:
        BaseEntity() {m_type = EntityType::Base;}
        virtual ~BaseEntity() {  }

        virtual void Draw(sf::RenderWindow *l_window) = 0;
        virtual void Update(sf::Time &l_time) = 0;

        //getters
        ...
};
 
Each inheritable class has its own draw function. Like so:
class Player : public BaseEntity {
private:

public:
        Player()
        {
                m_name = ""; m_health = 100; m_type = EntityType::Player;
                m_sprite.setFillColor(sf::Color::Red);
                m_sprite.setSize(sf::Vector2f(100, 100));
                m_sprite.setOrigin(sf::Vector2f(m_sprite.getSize().x / 2, m_sprite.getSize().y / 2));
        }
        ~Player() {};

        void Draw(sf::RenderWindow *l_window) {
                l_window->draw(*GetSprite());
        }

        ...
};
 
Why is it leaking? Oh, and here are the containers that use to store all the entitites:
For the factory, I use std::unordered_map<EntityType, std::function<BaseEntity*()>> m_entityFactory;
And for the actual entities I use std::unordered_map<unsigned int, BaseEntity*> m_entities;
What's wrong here?

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: SFML Draw method leaking memory?
« Reply #1 on: October 22, 2020, 09:50:17 am »
It's not uncommon that reporting tools provide false positives, e.g. if they don't account for the destruction of some objects at application termination.

But if there really is an issue with SFML, then it should be reproducible in a few lines of code.
Given that you're doing manual memory management with raw pointers, I'd claim, that the leaks are originating somewhere from your own code. I highly recommend using unique_ptr (or if necessary shared_ptr) and not do any manual memory management.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

PoppingNuts

  • Newbie
  • *
  • Posts: 2
    • View Profile
    • Email
Re: SFML Draw method leaking memory?
« Reply #2 on: October 23, 2020, 12:40:25 am »
It's not uncommon that reporting tools provide false positives, e.g. if they don't account for the destruction of some objects at application termination.

But if there really is an issue with SFML, then it should be reproducible in a few lines of code.
Given that you're doing manual memory management with raw pointers, I'd claim, that the leaks are originating somewhere from your own code. I highly recommend using unique_ptr (or if necessary shared_ptr) and not do any manual memory management.

Yes, I think you're right. I know  a lot about unique pointers, but when should I use shared?

mohragk

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: SFML Draw method leaking memory?
« Reply #3 on: November 11, 2020, 03:13:20 pm »
Well, a shared pointer is a reference counted pointer and is useful when multiple sources need access to the pointer. The object is kept alive as long as there are shared pointers for it. If not, the object is deleted.

Just take a look at:
https://en.cppreference.com/book/intro/smart_pointers