【问题标题】:Compound data structure and fiddling with pointers复合数据结构和摆弄指针
【发布时间】:2014-12-25 16:28:05
【问题描述】:

我正在尝试创建一个由四叉树和简单 STL 向量组成的复合数据结构类,因为我希望能够跨时间范围访问数据(即保持插入对象的顺序)。我最初的实现是维护一个MyObject 的STL 向量和一个const MyObject * const 四叉树。

不用说,我意识到在删除这个复合数据结构的那一刻之后不久,并不能保证首先删除四叉树和 STL 向量(保存基础数据),因此可能存在内存问题可能会发生。

我正在考虑在插入新对象时在堆上创建一个 MyObject 实例,并且四叉树和 STL 向量基本上都保存指向该实例的指针(使用 shared_ptr 或其他什么?)

有更好的建议吗?

编辑:这是我迄今为止的实现。我认为只有insertretrieve... 函数可能是有意义的

头文件:

#include "MapQuadTree.hpp"

typedef cv::Point2d Coordinate_t;

class PointsData
{
private:
    const unsigned int mMaxLevels = 10;
    const unsigned int mMaxPerLevel;

    unsigned int mMaxDataSize;
    unsigned int mCurrentIndex;

    std::vector<Coordinate_t> mPointsVector;
    MapQuadTree mPointsQuadtree;

public:
    PointsData(const unsigned int maxDataSize, double mapWidth, double mapHeight);
    ~PointsData();

    Coordinate_t operator[](int index);
    Coordinate_t last();
    Coordinate_t first();

    bool insert(const Coordinate_t& point);
    void retrieveNeighboringPoints(const Coordinate_t& point, std::vector<Coordinate_t>& neighbors);
};

源文件:

#include "PointsData.hpp"


PointsData::PointsData(const unsigned int maxDataSize, double mapWidth, double mapHeight)
: mMaxPerLevel(maxDataSize / mMaxLevels), mMaxDataSize(maxDataSize), mPointsVector(maxDataSize), mCurrentIndex(0),
mPointsQuadtree(0, maxDataSize / mMaxLevels, mMaxLevels, Coordinate_t(-1.0*mapWidth/2, -1.0*mapHeight/2), mapWidth, mapHeight)
{
}


PointsData::~PointsData()
{
}


Coordinate_t PointsData::operator[](int index)
{
    return mPointsVector[index];
}

Coordinate_t PointsData::last()
{
    return mPointsVector.back();
}

Coordinate_t PointsData::first()
{
    return mPointsVector.front();
}

bool PointsData::insert(const Coordinate_t& point)
{
    if (mCurrentIndex >= mMaxDataSize)
        return false;

    mPointsVector[mCurrentIndex] = point;
    mPointsQuadtree.insert(&mPointsVector[mCurrentIndex]);
    mCurrentIndex++;
    return true;
}

void PointsData::retrieveNeighboringPoints(const Coordinate_t& point, std::vector<Coordinate_t>& neighbors)
{
    std::vector<const Coordinate_t * const> results;
    mPointsQuadtree.retrieve(point, results);
    neighbors.clear();
    for (const Coordinate_t * const elemPtr : results) {
        neighbors.push_back(*elemPtr);
    }
}

【问题讨论】:

  • “有更好的建议吗?” 没有简明的样本很难说。您确定需要shared_ptr,还是需要unique_ptr

标签: c++ pointers vector data-structures stl


【解决方案1】:

内存管理应委托给您的容器。一个可能的建议应该是在您的向量中使用智能指针,如下所示: std::vector&lt;std::shared_ptr&lt;MyObject&gt;&gt; 如果保存您的对象的内存将被共享或std::vector&lt;std::unique_ptr&lt;MyObject&gt;&gt; 如果该内存将不被共享。

【讨论】:

  • 我最终为四叉树和std::vector&lt;std::shared_ptr&lt;MyObject&gt;&gt; 使用了一个shared_ptr,并在每次插入对象时使用std::make_shared 在堆上创建一个对象。它工作得很好,而且更容易管理
【解决方案2】:

我认为您的原始设计没有特别的问题。

只有在向量被销毁后尝试取消引用四叉树中的指针时,才会出现内存问题。实际的破坏顺序并不那么重要。

如果四叉树和向量都由同一个对象管理,它们将在同一时间被管理对象的析构函数销毁,一切都会好起来的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-15
    相关资源
    最近更新 更多