I have to put few megabytes of data in two-dimensional arrays in C++ code (embed it in DLL), diffrent datasets for each subclass. I defined virtual accessor methods to access constants to specified subclass but it works only for primitives and 1D arrays, not for 2D arrays:
#include <stdio.h>
class SubClassHoldingData { // inheritance removed for short,compilable example
public:
static int const notWorkingData[2][2];
virtual int const** getNotWorkingData() { return (int const**)notWorkingData; }
};
// simplified data set, about 200x200 in real application
const int SubClassHoldingData::notWorkingData[2][2] = { { 1 , 2 } , { 3, 4 } };
int main( int argc , char** argv ) {
SubClassHoldingData* holder = new SubClassHoldingData();
const int** data = holder->getNotWorkingData();
printf("data: %d" , data[1][1]); // !!! CRASHES APPLICATION !!!
}
I want to access data dynamiccaly (virtual) but with compile-time constant array like this:
DataHolder* holder = new FirstDataSetHolder();
const int** data = holder->get2DArray();
DataHolder* holder = new SecondDataSetHolder();
const int** data = holder->get2DArray();
// "data" contents DIFFERENT now, but compile-time constants!
How to achieve that?
If I understand the issue right, your problem is actually "how to return a pointer to pointer to some data that is in a 2D array".
The problem with two layer pointers and 2D arrays is that a 2D array doesn't automatically make a pointer to pointer - they are two different things. A 2D array T arr[Y][X];
is a lump of memory of Y * X elements, where the offset to arr[a][b]
is calculated as a * X + b
.
If we use the same arr[Y][X]
in a dynamically allocated scenario, we would allocate a lump of memory Y
long, and populate that with pointers to T
that to a lump of memory X
long each. So when we want to find arr[a][b]
, we first dig out pointer arr[a]
, then using that pointer add b
elements to that.
For your code to work, you would have to build that first array of pointers to each row in your array. Or return a pointer to an array with a fixed size for the [X]
dimension, e.g.
Edited:
typedef int arr[X];
...
class SomethingHolder
{
...
arr* get2DArray();
...
};
const arr* data = holder->get2DArray();
[I think it's technically possible to declare a function as returning a pointer to an array of integers, but I clearly didn't get the syntax right from my "obvious" type, and when trying to figure it out, I still couldn't get it right, so I gave up and used typedef of arr].
Note that X must be a compile-time constant that is the same for the whole range.
Another option is of course to have a holder->getData(x, y)
that returns the actual data at [y][x]
(or [x][y]
depending on which way makes most sense).