Reputation: 1129
I've read a lot of question but no one answer me for my specific case.
Actually I have
std::vector<Point2Dd> points;
std::vector<Triangle> triangles;
Point2Dd
is a class for a 2D point, it is not important to specify how it is implemented.
Triangle however is implemented like:
class Triangle{
public:
Triangle();
Triangle(Point2Dd* p1, Point2Dd* p2, Point2Dd* p3);
// Getter & setter
private:
Point2Dd* vA = nullptr;
Point2Dd* vB = nullptr;
Point2Dd* vC = nullptr;
}
that is, as three-pointers to vector of points.
Actually it work perfectly but I've think: if I add an other point into my vector and my vector change all memory address? All my triangles will be composed by invalid address.
I've read about using std::unique_ptr<Point2Dd>
but I don't think is the best way.
Have you any solution? Thanks :)
--- EDIT 1 ---
To clarify my problem I explain what problem I'm trying to solve. I'm doing an incremental Delaunay Triangulation (no problem with that). So I have to add once by once a point and update my triangulation.
So I've think to manage triangle as a three pointer to my points. Also I have a dag (Node -> Triangles with three children) and a structure that save adjacent triangles.
This is why I've thinked to use always a pointer, so I don't have to copy in three different structures the same points.
This is why I need to solve this problem to prevent memory reallocation.
Upvotes: 2
Views: 2798
Reputation: 1254
Two simple options:
Use an std::vector<Point*>
. Fill it with new
and empty it with delete
. Your points will live on the heap and they won't be invalidated when the vector grows.
Call std::vector::reserve
with size n
before you push_back
the points. reserve
allocates space for the vector's data, so addresses won't be invalidated unless you push_back
more than n
points. std::vector::resize
could also work but check documentation first as it's slightly different.
Edit:
Upvotes: 2
Reputation: 66230
I've read about using std::unique_ptr but I don't think is the best way
And what about shared pointers ?
I mean... if your Triangle
class contains three std::shared_ptr<Point2Dd>
, instead of three old style pointers, and if points
is a std::vector<std::shared_ptr<Point2Dd>>
instead of a vector of Points2Dd
, you should able to write something as the following example
#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]);
}
p.s.: if isn't important that all the element of points
are stored in a unique sequential area, I suggest you to consider the use of std::deque
instead of std::vector
Upvotes: 0
Reputation: 69902
Yes because after this I've a very heavy algorithm, so I need to optimize all as I can..
In this case, start with copies of data.
struct Triangle{
Triangle();
Triangle(Point2Dd p1, Point2Dd p2, Point2Dd p3);
// Getter & setter
private:
Point2Dd vA, vB, vC;
};
Although measurement is the only way to know for sure, the loss of cache locality and the indirect memory access inherent in a pointer-based solution is almost certain to result in run times an order of magnitude slower.
Upvotes: 6