Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
Solved

# How to cast a void pointer to a multi array pointer in ISO c++?

Posted on 2004-10-15
Medium Priority
1,098 Views
Hi everyone,

i have the following problem,
I want to cast a void pointer to a pointer for a 2d-array with bounds. My code that does NOT work look like this:

double (*newArr)[(*border).grid][(*border).grid]=(double *[(*border).grid][(*border).grid]) (*border).Arr1;
where grid is a int, newArr is suppose to become the pointer to the 2d-array, Arr1 is a void pointer that in a structure pointed to by border and Arr1 points to the array that i really want to point to.

0
Question by:Rawer
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points

LVL 86

Expert Comment

ID: 12322872
1st of all, array bounds need to be constants. 2nd, an array name itself is a pointer. So, if you have

double some_arr[20][30];

void* p = (void*) some_arr;

double*** pd = (double***) p;

The above line *really* looks confusing. Maybe you'd want to take a look at a matrix library like MTL (http://www.osl.iu.edu/research/mtl/) to make things a little simpler...

0

LVL 1

Expert Comment

ID: 12322882
You don't need the bounds when declaring a pointer to a matrix ( a 2d array).  Only when declaring the matrix itself. All you need is:

double ** newArray = (double **) Arr1;

You can then access elements in your array using something like:

double myDble = newarray[0][1];  // this will give you the double value in position (0,1)

hope this helps.

Gustavo.
0

Author Comment

ID: 12323993
jkr, how can I then access the elements? cuz it seg faults now...
0

Author Comment

ID: 12324003
when trying to access them like p[5][1] for example.
0

LVL 86

Expert Comment

ID: 12324118
How *are* you currectly accessing it? Remember, it is a pointer to an array, so in the above you'd have to use

double some_arr[20][30];

void* p = (void*) some_arr;

double*** pd = (double***) p;

double d = (*pd)[5][1]
0

LVL 1

Accepted Solution

RogueAce earned 1000 total points
ID: 12325585
After doing some experimenting with this (frankly, I've never tried this before), here's what I found:

double I[10][10];

I[0][0]=1.0;
I[2][0]=2.0;
I[1][0]=1.5;

void* vp = (void*)I;

double* n=(double*)vp;
cout << n[0] << endl << n[10] << endl << n[20] << endl;

This will (believe it or not) output
1.0
1.5
2.0

However, doing it the way jkr says results in a segmentation fault, as Rawer found. I don't think it's logical even to declare pd as a double*** (double** should suffice, since it's a pointer (array) of double pointers (arrays)). However, this also segfaults.

The reason is subtle and annoying: C++ stores its multidimensional arrays in row major form. This means that a 3x3 matrix that looks like
1 2 3
4 5 6
7 8 9
is stored in memory as 1 2 3 4 5 6 7 8 9. So when I accessed n[10], I was really accessing n[1 * (rowsize) + 0] (I was sort of expecting this, which I why I did it that way).

The problem is, a statically-sized multidimensional array is not really an array of arrays. The second problem is, if you try to say n[1][0], it won't compile...because to the compiler, a double pointer is different from a multidimensional array of doubles. But if you say something like double n[10][10] = (double*) vp, that is an incorrect initialization acording to the compiler.

Here is what you probably should do. Instead of using a multidimensional array, do something like this:

double** dpp = new double*[numRows];

for(unsigned int c=0;c<numRows;c++)
(*dpp)=new double[numCols];

Then you really DO have a double**, and the code will work the way jkr says it will. If this looks as dodgy to you as it does to me, you might want to seriously consider jkr's suggestion of using matrix templates. If you want to do one yourself, a vector of vectors (the STL vector is in c++ header <vector>) is a good quick way to implement one.

Good luck!
0

LVL 15

Expert Comment

ID: 12325727
Assuming you have a real two-dimensional array and not an array of pointers, I believe RogueAce's idea is the only one posted so far that will work, but it requires copying the whole array.  You can avoid that with a bit of pointer magic:  you would still have an array of pointers, but you can set them to point to the right places in the original data, so you don't have to copy it.  Something like this:

double originalArray[10][20];
void* pVoid = originalArray;
int rows = 10;
int columns = 20;
double** pseudoArray = new double*[rows];
double* pDouble = static_cast<double*>(pVoid);
for (int ndx = 0; ndx < rows; ++ndx)
{
pseudoArray[ndx] = pDouble + (ndx * columns);
}

--efn
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, whâ€¦
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilationâ€¦
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.
###### Suggested Courses
Course of the Month10 days, 5 hours left to enroll