patterncppMinor
Vector of vectors in contiguous memory
Viewed 0 times
vectorsvectormemorycontiguous
Problem
I have a class
I would like to hear what you think about this piece of code. Can this be considered a goo
Vector3d with 3 double components and want to store several of them in a Field. For reasons of efficiency when sending a Field over a network via MPI, I would like to allocate contiguous memory in the Field class and let the Vector3ds store their components in that chunk of memory. In addition, Vector3ds should also be able to live without a Field; in this case, they have to care about their own memory allocation.#include
#include
#include
class Field;
class Vector3d
{
friend class Field;
public:
Vector3d() : components_(new double[3]) {}
~Vector3d() { delete[] components_; }
Vector3d(const Vector3d &v) : components_(new double[3])
{
components_[0] = v.components_[0];
components_[1] = v.components_[1];
components_[2] = v.components_[2];
}
double & operator()(const std::size_t index) { return components_[index]; }
private:
Vector3d(double *ptr) : components_(ptr) {};
double *components_;
};
class Field
{
public:
Field(std::size_t size);
~Field();
Vector3d & operator()(const std::size_t index) { return *(vectors_[index]); }
private:
std::vector components_;
std::vector vectors_;
};
Field::Field(std::size_t size) : components_(std::vector(3 * size)), vectors_(std::vector(size, new Vector3d(0)))
{
double *ptr = &components_[0];
for (auto it = vectors_.begin(); it != vectors_.end(); ++it)
{
(*it)->components_ = ptr;
ptr += 3;
}
}
Field::~Field()
{
for (auto it = vectors_.begin(); it != vectors_.end(); ++it)
(*it)->components_ = 0;
}
int main(int argc, char *argv[])
{
Field field(2);
Vector3d &v = field(1);
v(2) = 5;
Vector3d v2 = v;
v2(2) = 2;
std::cout << field(1)(2) << std::endl;
return 0;
}I would like to hear what you think about this piece of code. Can this be considered a goo
Solution
When it comes to multidimensional vectors I usually suggest two approaches.
This only works, when the inner dimensions are fixed and only the outer is runtime dynamic. In the end it comes down to something like this:
In your case a Vector3d would either derive from std::array or contain one.
This approach simply creates a one dimensional vector with
The element
Bonus
I just want to highlight @Yakk's comment. Your Vector3d could look like this:
This way the memory would also be contigous.
- vector/array (C++11 and later)
This only works, when the inner dimensions are fixed and only the outer is runtime dynamic. In the end it comes down to something like this:
std::vector> field;In your case a Vector3d would either derive from std::array or contain one.
- simple vector
This approach simply creates a one dimensional vector with
X * Y size.The element
(x, y) can then be addressed with vec[y * X + x]. This works also with the older C++ standard. Although I think this solution might not work in your setup.Bonus
I just want to highlight @Yakk's comment. Your Vector3d could look like this:
class Vector3d
{
public:
// stuff
// ...
private:
double components_[3];
};This way the memory would also be contigous.
Code Snippets
std::vector<std::array<T, N>> field;class Vector3d
{
public:
// stuff
// ...
private:
double components_[3];
};Context
StackExchange Code Review Q#83912, answer score: 4
Revisions (0)
No revisions yet.