2

I am trying to create a class grid which contains the data members unsigned NR, unsigned NC and it should also contain a 2D array double Coordiantes[NR][NC]. I wish to initialize the data members NR and NC through the class constructor. I am trying to avoid the dynamic allocation of the 2-D array as I prefer contiguous memory allocation so as to avoid the cache misses as much as possible.

I am not sure if it is possible but any inputs would be helpful.

mustafagonul
  • 1,139
  • 1
  • 15
  • 32
user3496912
  • 195
  • 1
  • 6

2 Answers2

15
class Array2D {
public:
    vector<int> v;
    int nc;
    Array2D(int NR, int NC) : v(NR*NC), nc(NC) {}
    int* operator[](int r) { return &v[r*nc]; }
};

int main()
{
    Array2D array2d(2, 3);
    array2d[0][0] = 1;
    array2d[1][2] = 6;
}

This allows you to create a class that will function like a 2D array. It's fast and the data is contiguous.

doug
  • 3,840
  • 1
  • 14
  • 18
  • This is the cleanest implementation I've seen. Especially nice is the usage of the **built-in operator []** to access the contents without the need to implement it specifically for the second dimension. – SomeWittyUsername Mar 21 '16 at 07:05
  • @SomeWittyUsername - Thanks! Probably helped that I was originally a C programmer. I do love modern c++ though. – doug Mar 21 '16 at 07:23
  • Interesting but somewhat risky - with `int*` there is no way to assert a validity of `a[i][j]` expression. – Evg Oct 25 '22 at 02:47
  • 1
    @Evg So true. I actually prefer the (r,c) approach and it's easy to bounds conditionally check, It's a minimalist approach with conventional brackets. Simplest thing i could think of. I currently use a ptr, row, and col. All consts in a constexpr class. An even smaller object footprint but very fast. And const correct thanks to c++20. – doug Oct 25 '22 at 03:03
  • If you can stretch to C++20, returning a `std::span` from the array operator would allow bounds checking. Not zero overhead though, since the extent is dynamic. – Useless Dec 16 '22 at 15:31
2

I recommend you simply use std::vector<double>(NC*NR).
And index into it by coord.at(i*NC + j) (or coord[i*NC + j], when you code is correct and you want to glean performance out of it).

You'll get contiguous memory and cache friendly loops without doing your own memory allocation. Always prefer RAII when possible.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458