1

how can I cast void pointer to a 2d array (array of pointers to arrays of ints), when I dont know array size at compile time? Is it somehow possible? (I am doing this because, I pass an 2d array of unknow size to a func. So I cast 2d array to a void pointer and then in that func I want it to recast back.)

int i = 5;

int tab1[i][i];

//cast to void pointer
void *p = (void *)tab1;

//and recast back
int (*tab2)[5] = (int (*)[5])p;   //this is working
int (*tab3)[i] = (int (*)[i])p;   // but this is not
4
  • 1
    you cannot int tab1[i][i]; when i is not a compile time constant Commented May 28, 2020 at 10:58
  • 2
    Note that int tab1[i][i]; is not standard C++ and is a compiler extension. For arrays where the size is determined at runtime use std::vector Commented May 28, 2020 at 10:58
  • You can't. You need to come up wih a different solution to whatever your original problem is. Commented May 28, 2020 at 11:01
  • Also, a 2D array (of ints) is not an array of pointers to arrays of ints. It is an array of arrays of ints. That is not the same thing. Commented May 28, 2020 at 13:14

4 Answers 4

2
  1. int i = 5; int tab1[i][i]; is a VLA. It's not standard C++ and should be avoided.

  2. An array-of-pointers-to-arrays (and vector-of-vectors) won't be as efficient as a true 2D array since it's no longer contiguous (int tab1[5][5] is a true 2D array and is stored contiguously in memory, but the dimensions must be known at compile-time).

  3. You can easily create a custom 2D container class that would store the data in a contiguous 1D vector and apply some simple math (x + y*width) to access the elements.

Example:

class Matrix {
    std::vector<int> data;
public:
    const int width;
    const int height;

    Matrix(int width, int height) : width(width), height(height), data(width*height) {}

    int operator()(int x, int y) const {
        return data[y * width + x];
    }

    int& operator()(int x, int y) {
        return data[y * width + x];
    }

};

void print(Matrix const& mat) {
    for (int y = 0; y < mat.height; y++) {
        for (int x = 0; x < mat.width; x++)
            std::cout << mat(x, y) << " ";
        std::cout << std::endl;
    }
}

int main() {
    Matrix mat(5, 5);
    mat(1, 1) = 1;
    mat(2, 2) = 2;
    mat(3, 3) = 3;

    print(mat);
}

For convenience this overloads the () operator. It's still possible with the [] operator but that will require a proxy class to access the inner dimension(s) and also putting y before x since the dimensions are actually reversed.

Sign up to request clarification or add additional context in comments.

Comments

0

First I suggest to don't use runtime size for array in C/C++, except you using STL vector as an array. so instead of:

int i = 5;

you must use:

const int i = 5;

except you use Vector that is safe and better than intrinsic arrays.

how can I cast void pointer to a 2d array (array of pointers to arrays of ints), when I dont know array size at compile time? Is it somehow possible?

If we talk about C intrinsic array, It is not possible!

why it is not possible? because C/C++ compiler not aware of your the array size, borders,.... so if you cast your 2d array to 1d array, it is possible. it is the reason that tab2 array can access to first 5th element of your array. really C/C++ compiler cannot distinguish the different of

int a[3][3]

with

int a[3*3]

so You must be aware of at least one dimension of your array:

int main() {
    const int i = 3,j = 4;

    int tab1[i][j] = {1,2,3,4,5,6,7,8,9,10,11};

//cast to void pointer
    void *p = (void *)tab1;

    auto a = (int (*)[i][12/i])p;
    return 0;
}

In the above example, I aware about i and total count(12) and I calculate the second dimension. I use auto keyword that very easily inferred the data type.

Comments

0

int tab1[i][i]; is a non-standard compiler extension for variable length arrays. It is better to avoid this because it is not portable and hard to deal with as you are seeing. You would be better with:

std::vector<std::vector<int>> tab1(i, std::vector<int>(i));

Then your function can simply take this vector:

void foo(const std::vector<std::vector<int>>& array) { ....

2 Comments

It sounds good, but I tried to solve it just with basic language options. I will look at that library, thanks.
This isn't some library, its part of the c++ standard. Any compiler giving you c++ will provide this for you.
0

how can I cast void pointer to a 2d array (array of pointers to arrays of ints), when I dont know array size at compile time?

You can't. You can only cast to a type that is known at compile time.

What you can do is convert to a pointer to first element of the first row: int* p = static_cast<int*>(tab1);. You can then treat the array as one dimensional1. Converting two dimensional indices to one dimensional requires some trivial math: x, y -> x + y * i.


1 As long as you don't mind the technicality that pointer arithmetic across the sub array boundary might technically not be allowed by the standard. But that rule is silly. If you're concerned about this, then you should create a one dimensional array in the first place.

1 Comment

Yes, thought about this, but I tried to look for another solution then one dimensional array. Thank you for your reply

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.