Solved

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

Posted on 2004-10-15
7
940 Views
Last Modified: 2010-08-05
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.

What should i write instead? please help!
0
Comment
Question by:Rawer
7 Comments
 
LVL 86

Expert Comment

by:jkr
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

by:gugario
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

by:Rawer
ID: 12323993
jkr, how can I then access the elements? cuz it seg faults now...
0
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 

Author Comment

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

Expert Comment

by:jkr
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

by:
RogueAce earned 250 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

by:efn
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

Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

Question has a verified solution.

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

C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

808 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question