如何使用std :: vector防止内存重新分配

时间:2017-08-15 10:14:46

标签: c++ c++11 pointers vector smart-pointers

我已经阅读了很多问题,但没有人回答我的具体案例。

其实我有

std::vector<Point2Dd> points;
std::vector<Triangle> triangles;

Point2Dd是2D点的类,指定它的实现方式并不重要。

Triangle实现如下:

class Triangle{
    public:
     Triangle();
     Triangle(Point2Dd* p1, Point2Dd* p2, Point2Dd* p3);
     // Getter & setter

    private:
     Point2Dd* vA = nullptr;
     Point2Dd* vB = nullptr;
     Point2Dd* vC = nullptr;
}

即,作为点向量的三个指针。

实际上它工作得很好,但我想:如果我在向量中添加另一个点,我的向量会更改所有内存地址吗?我的所有三角形都将由无效地址组成。

我读过关于使用std::unique_ptr<Point2Dd>的内容,但我认为这不是最佳方法。

你有解决方案吗? 谢谢:)

---编辑1 ---

为了澄清我的问题,我解释了我想要解决的问题。 我正在做增量Delaunay三角测量(没问题)。 所以我必须每次添加一次并更新我的三角测量。

所以我认为将三角形作为指向我的点的三个指针来管理。我还有一个dag(Node - &gt; Triangles with three children)和一个保存相邻三角形的结构。

这就是为什么我认为总是使用指针,所以我不必在三个不同的结构中复制相同的点。

这就是我需要解决此问题以防止内存重新分配的原因。

3 个答案:

答案 0 :(得分:6)

  

是的,因为在此之后我有一个非常繁重的算法,所以我需要尽可能优化所有...

在这种情况下,请从数据副本开始。

struct Triangle{
     Triangle();
     Triangle(Point2Dd p1, Point2Dd p2, Point2Dd p3);
     // Getter & setter

    private:
     Point2Dd vA, vB, vC;
};

虽然测量是唯一可以确定的方法,但基于指针的解决方案中固有的缓存局部性和间接内存访问的丢失几乎肯定会导致运行时间慢一个数量级。

答案 1 :(得分:1)

两个简单的选择:

  1. 使用std::vector<Point*>。填写new并用delete清空它。你的积分将存在于堆中,当向量增长时,它们不会失效。

  2. 在点std::vector::reserve之前调用n大小为push_back的{​​{1}}。 reserve为向量的数据分配空间,因此除非push_back超过n分,否则地址不会失效。 std::vector::resize也可以有效,但请先检查文档,因为它略有不同。

  3. 编辑:

    1. 一位评论者提到保存指数,这是一个好主意,可能比所有这些都简单。

答案 2 :(得分:0)

  

我读过关于使用std :: unique_ptr的内容,但我认为这不是最好的方法

那么共享指针呢?

我的意思是......如果您的Triangle类包含三个std::shared_ptr<Point2Dd>,而不是三个旧样式指针,并且pointsstd::vector<std::shared_ptr<Point2Dd>>而不是一个向量Points2Dd,您应该能够编写一些内容,如以下示例所示

#include <memory>
#include <vector>

struct Point2Dd
 { };

class Triangle
 {
   private:
      using sp2Dd = std::shared_ptr<Point2Dd>;

      sp2Dd vA, vB, vC;

   public:
      Triangle()
       { }

      Triangle (sp2Dd const & p1, sp2Dd const & p2, sp2Dd const & p3)
         : vA{p1}, vB{p2}, vC{p3}
       { }
 };

int main ()
 {
   std::vector<std::shared_ptr<Point2Dd>> points;
   std::vector<Triangle>                  triangles;

   points.emplace_back(new Point2Dd{}); // or using std::make_shared(),
   points.emplace_back(new Point2Dd{}); // if C++14 is available
   points.emplace_back(new Point2Dd{});

   triangles.emplace_back(points[0U], points[1U], points[2U]);
 }

ps:如果points的所有元素都存储在一个唯一的顺序区域中并不重要,我建议您考虑使用std::deque代替std::vector