mardi 14 mars 2023

I made an object pool and used it in the set/vector/map container. When it is released, it always crashes. I don't know why

I use a simple MFC CDialog project for code experiments. When I exit CDialog, I always crash when I release the pointer. The following is the structure code of my data storage

#include <set>
#include <map>
#include <string>
#include <memory>
#include <vector>
using namespace std;
#define SAFEDELETE(p) {if (p) { delete p; p = nullptr;}}
class CName
{
public:
    bool operator < (const CName& other) const
    {
        if (this->_server.compare(other._server) != 0)
        {
            return this->_server < other._server;
        }
        if (this->_source.compare(other._source) != 0)
        {
            return this->_source < other._source;
        }
        return false;
    }
public:
    string _server;
    string _source;
};

class Attributes
{
    public:
        Attributes() {}
        ~Attributes()
        {
            _enabled = false;
            _lTimeStamp = 0;
        }
        bool _enabled = false;
        long _lTimeStamp = 0;
};
using AttributesPtr = shared_ptr<Attributes>;
class TimeStampCompare
{
public:
    bool operator()(const AttributesPtr attr1, const AttributesPtr attr2) const
    {
        if (attr1 == nullptr || attr2 == nullptr)
        {
            return false;
        }
        return attr1->_lTimeStamp > attr2->_lTimeStamp;
    }
};
class Container;
using ContainerPtr = shared_ptr<Container>;
class Container
{
public:
    Container() {}
    ~Container()
    {
        Clear();
    }
    void Clear()
    {
        _name = "";
        _path = "";
        for (auto& iter : _cache)
        {
            iter.second.clear();
        }
        _cache.clear();
        _containers.clear();
    }
public:
        string _name;
        string _path;
        vector<ContainerPtr> _containers;
        map<CName, set<AttributesPtr, TimeStampCompare>> _cache;
};

Here is the code of my object pool

template <typename T>
class ObjectPool
{
public:
    ObjectPool(std::size_t size)
    {
        for (std::size_t i = 0; i < size; i++)
        {
            T* obj = new T();
            m_objs.push_back(obj);
        }
    }
    virtual ~ObjectPool()
    {
        for (auto iter = m_objs.begin(); iter != m_objs.end(); iter ++)
        {
            delete (*iter);
        }
        m_objs.clear();
    }
    template <typename... E>
    std::shared_ptr<T> getObject()
    {
        T* obj = iGetObject();
        if (obj != nullptr)
        {
            return std::shared_ptr<T>(obj, [this](T* ptr)->void
            {
                destroy1(ptr);
                std::unique_lock<std::mutex> lk(m_lock);
                m_objs.push_back(ptr);
            });
        }
        return nullptr;
    }   
private:
    std::deque<T*> m_objs;
    mutable std::mutex m_lock;
    T* iGetObject()
    {
        std::unique_lock<std::mutex> lk(m_lock);
        if (!m_objs.empty())
        {
            T* obj = m_objs.front();
            m_objs.pop_front();
            return obj;
        }
        return nullptr;
    }
    void destroy1(T* obj)
    {
        obj->~T();
    }
};

The following is the code for creating member variables and destructing in CMyDialog

//CMyDialog.h
ContainerPtr _root;
ObjectPool<Container>* _ContainerPool = nullptr;
ObjectPool<Attributes>* _AttributePool = nullptr;
//CMhDialog.cpp
//construction
_ContainerPool = new ObjectPool<Container>(1);
_AttributePool = new ObjectPool<Attributes>(1);
_root = _ContainerPool->getObject();
//destruction
_root = nullptr;
SAFEDELETE(_ContainerPool);
SAFEDELETE(_AttributePool);

Every time I call SAFEDELETE(_ContainerPool) in destruction, it will crash. I don't know why, I hope it can be released normally

Aucun commentaire:

Enregistrer un commentaire