I am trying to make my own implementation of shared_ptr. I have problems with make_shared. The main feature of std::make_shared that it allocates counter block and object in continuous block of memory. How I can do the same? 
I tried do something like that:
template<class T>
class shared_ptr
{
private:
    class _ref_cntr
    {
    private:
        long counter;
    public:
        _ref_cntr() :
            counter(1)
        {
        }
        void inc()
        {
            ++counter;
        }
        void dec()
        {
            if (counter == 0)
            {
                throw std::logic_error("already zero");
            }
            --counter;
        }
        long use_count() const
        {
            return counter;
        }
    };
    template<class _T>
    struct _object_and_block
    {
        _T object;
        _ref_cntr cntr_block;
        template<class ... Args>
        _object_and_block(Args && ...args) :
            object(args...)
        {
        }
    };
    T* _obj_ptr;
    _ref_cntr* _ref_counter;
    void _check_delete_ptr()
    {
        if (_obj_ptr == nullptr)
        {
            return;
        }
        _ref_counter->dec();
        if (_ref_counter->use_count() == 0)
        {
            _delete_ptr();
        }
        _obj_ptr = nullptr;
        _ref_counter = nullptr;
    }
    void _delete_ptr()
    {
        delete _ref_counter;
        delete _obj_ptr;
    }
    template<class _T, class ... Args>
    friend shared_ptr<_T> make_shared(Args && ... args);
public:
    shared_ptr() :
        _obj_ptr(nullptr),
        _ref_counter(nullptr)
    {
    }
    template<class _T>
    explicit shared_ptr(_T* ptr)
    {
        _ref_counter = new counter_block();
        _obj_ptr = ptr;
    }
    template<class _T>
    shared_ptr(const shared_ptr<_T> & other)
    {
        *this = other;
    }
    template<class _T>
    shared_ptr<T> & operator=(const shared_ptr<_T> & other)
    {
        _obj_ptr = other._obj_ptr;
        _ref_counter = other._ref_counter;
        _ref_counter->inc();
        return *this;
    }
    ~shared_ptr()
    {
        _check_delete_ptr();
    }
};
template<class T, class ... Args>
shared_ptr<T> make_shared(Args && ... args)
{
    shared_ptr<T> ptr;
    auto tmp_object = new shared_ptr<T>::_object_and_block<T>(args...);
    ptr._obj_ptr = &tmp_object->object;
    ptr._ref_counter = &tmp_object->cntr_block;
    return ptr;
}
But when I delete object and counter block, the invalid heap block exception occurs.
 
     
    