Solved

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

Posted on 2004-10-15
7
925 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
Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

 

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

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

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

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
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.

803 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