Solved

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

Posted on 2004-10-15
7
893 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
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 

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

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

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. …
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…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
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…

708 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

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now