(reformatted) How to return Multi-Dimensional Arrays

Please support our C++ advertiser: Intel Parallel Studio Home
Reply

Join Date: May 2004
Posts: 12
Reputation: TJW is an unknown quantity at this point 
Solved Threads: 0
TJW TJW is offline Offline
Newbie Poster

(reformatted) How to return Multi-Dimensional Arrays

 
0
  #1
May 28th, 2004
Hello:
(I am using Borland C++ Builder 6 Professional)

Before you jump all over me I've already read the post Returing Arrays C/C++ and completely understand. For some reason I am still having difficulty implementing in my project.

Very brief Project Explanation:

I am collecting data from a laser sensor and want to display my data in cartesian coordinates. I've already created a class that has captured the raw data, converted it to cartesian coordinates and stored these coordinates in an array. Return the array to my main form is what I am having trouble with.

Here is a snippet of the member functions I am referring to
(sorry about the long code most of which is of no interest to you)
data gets stored in array xyz_data

[PHP]void scan_data::add_image(VARIANT & data_array)
{
if (current_scan>=10)
{
current_scan=0;
}

// Check if the variant contains a SAFEARRAY
// Check if the SAFEARRAY is 1D
if (SafeArrayGetDim (V_ARRAY (&data_array)) != 1 )
{
// Not a 1D SAFEARRAY
throw ("Logic error css_image::add_image()");
}

SAFEARRAY * pArray = V_ARRAY (&data_array);

long * prgn;
long elements;
long i, peaks;

// Get bounds of array and a pointer to its data
if ((FAILED (SafeArrayGetLBound (pArray, 1, &i))) ||
(FAILED (SafeArrayGetUBound (pArray, 1, &elements)))||
(FAILED (SafeArrayAccessData (pArray, (void **)&prgn))))
{
// Failed to get bounds or pointer
throw ("HRESULT error css_image::add_image()");
}

// Create a new image


elements += 1-i;
long * end = prgn + elements;

int j=0;
unsigned int pos, str;
scan_points[current_scan]=0;
long ii;

while (prgn != end)
{
scan_points[current_scan]+=1;
long state=(*prgn)&0xFFFF;
ii=(*prgn&0xFFFF0000)>>16;
++prgn;
if (ii > 0) //check if any peaks exist, if they do, get position and strength
{
//store the first peak in the raw_data array at the position of the next available scan
pos=*prgn;
raw_pos[current_scan][j]=pos;
str=*(prgn+1);
raw_str[current_scan][j]=str;
prgn+=2;
}
switch(state)
{
case 0,void_sample:
status[current_scan][j]=dropout;
break;
case saturated_sample:
status[current_scan][j]=saturated;
break;
case good_sample:
status[current_scan][j]=normal;
break;
default:
status[current_scan][j]=dropout;
}
j++;

if (j>=Cycle)
{
break;
}

--ii;
while (ii >0)
{
//ignore the results of the remaining peaks for this pixel position
prgn+=2;
--ii;
}
}

SafeArrayUnaccessData (pArray);

// Make xyz data if we can
if (!pCurrentCSS)
{
// Can't make xyz data
return;
}

VARIANT xyz_array;
if (pCurrentCSS->convert_to_xyz (&data_array, &xyz_array)!=S_OK)
{
throw ("HRESULT error: css_image::add_image");
};
pArray = V_ARRAY (&xyz_array);

xyz_vector * pxyzelem;

// Get bounds of array and a pointer to its data
if ((FAILED (SafeArrayGetLBound (pArray, 1, &i))) ||
(FAILED (SafeArrayGetUBound (pArray, 1, &elements)))||
(FAILED (SafeArrayAccessData (pArray, (void **)&pxyzelem))))
{
// Failed to get bounds or pointer
throw ("HRESULT error css_image::add_image()");
}

elements += 1-i;
elements /= 3;


const double max = 10000.0;

for (i = 0; ((i < elements) && (i<Cycle)); ++i)
{
if (pxyzelem->x < max)
{
xyz_data[current_scan][0][i] = pxyzelem->x;
xyz_data[current_scan][1][i] = pxyzelem->y;
xyz_data[current_scan][2][i] = pxyzelem->z;
}
++ pxyzelem;
}

// Destroy the xyz safearray
SafeArrayUnaccessData (pArray);
SafeArrayDestroy (pArray);

current_scan++;
}[/PHP]

  1. void scan_data::get_image_data(double data[3][Cycle])
  2.  
  3. {
  4. int num_scans;
  5. bool flag_good;
  6. for (int i=0; i<Cycle; i++)
  7. {
  8. num_scans=0;
  9. flag_good=false;
  10. data[0][i]=0;
  11. data[1][i]=0;
  12. data[2][i]=0;
  13. for (int j=0; j<current_scan; j++)
  14. {
  15. if (pos_good(j,i))
  16. {
  17. data[0][i]+=xyz_data[j][0][i];
  18. data[1][i]+=xyz_data[j][1][i];
  19. data[2][i]+=xyz_data[j][2][i];
  20. num_scans++;
  21. flag_good=true;
  22. }
  23. else if (j==(current_scan-1)&& flag_good==false)
  24. {
  25. //no good scans were available for this pixel location
  26. data[0][i]=Bad;
  27. data[1][i]=Bad;
  28. data[2][i]=Bad;
  29. }
  30. }
  31. if (flag_good)
  32. {
  33. //compute average of all the scans collected
  34. data[0][i]/=num_scans;
  35. data[1][i]/=num_scans;
  36. data[2][i]/=num_scans;
  37. }
  38. }
  39. return;
  40. }

The data[][] array is what I need to return to my mainform. This is the original code and not any of my failed attempts.

Thanks in advance
Reply With Quote Quick reply to this message  
Join Date: May 2004
Posts: 141
Reputation: meabed is on a distinguished road 
Solved Threads: 3
Team Colleague
meabed's Avatar
meabed meabed is offline Offline
Junior Poster

Re: (reformatted) How to return Multi-Dimensional Arrays

 
0
  #2
May 28th, 2004
Array
An array is a collection of like objects. The simplest case of an array is a vector. C++ provides a convenient syntax for declaration of fixed-size arrays:

  1. decl-specifiers dname [ constant-expressionopt ] ;
The number of elements in the array is given by the constant-expression. The first element in the array is the 0th element, and the last element is the (n-1th) element, where n is the size of the array. The constant-expression must be of an integral type and must be greater than 0. A zero-sized array is legal only when the array is the last field in a struct or union and when the Microsoft extensions (/Ze) are enabled.

Arrays are derived types and can therefore be constructed from any other derived or fundamental type except functions, references, and void.

Arrays constructed from other arrays are multidimensional arrays. These multidimensional arrays are specified by placing multiple [ constant-expression ] specifications in sequence. For example, consider this declaration:

  1. int i2[5][7];

It specifies an array of type int, conceptually arranged in a two-dimensional matrix of five rows and seven columns, as shown in Figure 7.2.

Figure 7.2 Conceptual Layout of Multidimensional Array
http://msdn.microsoft.com/library/en...tm/vc38rc1.gif

In declarations of multidimensioned arrays that have an initializer-list (as described in Initializers), the constant-expression that specifies the bounds for the first dimension can be omitted. For example:

  1. const int cMarkets = 4;
  2.  
  3. // Declare a float that represents the transportation costs.
  4. double TransportCosts[][cMarkets] =
  5. { { 32.19, 47.29, 31.99, 19.11 },
  6. { 11.29, 22.49, 33.47, 17.29 },
  7. { 41.97, 22.09, 9.76, 22.55 } };
The preceding declaration defines an array that is three rows by four columns. The rows represent factories and the columns represent markets to which the factories ship. The values are the transportation costs from the factories to the markets. The first dimension of the array is left out, but the compiler fills it in by examining the initializer.

The technique of omitting the bounds specification for the first dimension of a multidimensioned array can also be used in function declarations as follows:

  1. #include <float.h> // Includes DBL_MAX.
  2. #include <iostream.h>
  3.  
  4. const int cMkts = 4;
  5.  
  6. // Declare a float that represents the transportation costs.
  7. double TransportCosts[][cMkts] =
  8. { { 32.19, 47.29, 31.99, 19.11 },
  9. { 11.29, 22.49, 33.47, 17.29 },
  10. { 41.97, 22.09, 9.76, 22.55 } };
  11. // Calculate size of unspecified dimension.
  12. const int cFactories = sizeof TransportCosts /
  13. sizeof( double[cMkts] );
  14.  
  15. double FindMinToMkt( int Mkt, double TransportCosts[][cMkts],
  16. int cFacts );
  17.  
  18. void main( int argc, char *argv[] )
  19. {
  20. double MinCost;
  21. MinCost = FindMinToMkt( *argv[1] - '0', TransportCosts,
  22. cFacts );
  23. cout << "The minimum cost to Market " << argv[1] << " is: "
  24. << MinCost << "\n";
  25. }
  26.  
  27. double FindMinToMkt( int Mkt, double TransportCosts[][cMkts],
  28. int cFacts )
  29. {
  30. double MinCost = DBL_MAX;
  31. for( int i = 0; i < cFacts; ++i )
  32. MinCost = (MinCost < TransportCosts[i][Mkt]) ?
  33. MinCost : TransportCosts[i][Mkt];
  34. return MinCost;
  35. }
The function FindMinToMkt is written such that adding new factories does not require any code changes, just a recompilation.
Attached Files
File Type: txt initializers.txt (1.6 KB, 3 views)
Real Eyes Realize Real Lies
My Resume
Reply With Quote Quick reply to this message  
Join Date: May 2004
Posts: 12
Reputation: TJW is an unknown quantity at this point 
Solved Threads: 0
TJW TJW is offline Offline
Newbie Poster

Re: (reformatted) How to return Multi-Dimensional Arrays

 
0
  #3
May 31st, 2004
Thanks for the info. However, my question has not been anwered. The above I am already aware of and anything I have forgotten I can go find my textbook from university. What I can not find in that stupid book is how to return and array/pointer properly I've tried the new/delete and get conversion errors etc. This is what I need help with: returning a multidimensional array(probably through a pointer but how?)

Again thank you.

Tim
Reply With Quote Quick reply to this message  
Join Date: May 2004
Posts: 53
Reputation: Natso is an unknown quantity at this point 
Solved Threads: 1
Natso Natso is offline Offline
Junior Poster in Training

Re: (reformatted) How to return Multi-Dimensional Arrays

 
0
  #4
May 31st, 2004
Originally Posted by TJW
Thanks for the info. However, my question has not been anwered. The above I am already aware of and anything I have forgotten I can go find my textbook from university. What I can not find in that stupid book is how to return and array/pointer properly I've tried the new/delete and get conversion errors etc. This is what I need help with: returning a multidimensional array(probably through a pointer but how?)

Again thank you.

Tim
Ok now I realise the problem, not using arrays but returning them.
Try making a global variable of some sort & instead of using 'return' just have the later parts of the program access the global variable created by your script that you are trying to add 'return' to.
Reply With Quote Quick reply to this message  
Join Date: May 2004
Posts: 12
Reputation: TJW is an unknown quantity at this point 
Solved Threads: 0
TJW TJW is offline Offline
Newbie Poster

Re: (reformatted) How to return Multi-Dimensional Arrays

 
0
  #5
May 31st, 2004
This what I've done and get:

I've moved array xyz_data[10][3][512] from being a private data member to a public data member of class scan_data. Called my member function(scan_data::add_image)(see above) that does the wanted conversion and stores that data into the now public xyz_data[10][3][512] array.

In the main form of my project I've cut & pasted the code for my member function get_image_data to avoid having to pass and return my array. Below is that snippet:

  1. {
  2. long scan_id,scan_length;
  3. double *pelem;
  4.  
  5. if(scan_counter>9)
  6. scan_counter=0;
  7.  
  8.  
  9. css->get_scan(&scan_id,&scan_time,&scan_length,&data);
  10. // css_data->Add_Image_Data(data);
  11. scans.add_image(data);
  12. VariantClear(&data);
  13. VariantClear(&scan_time);
  14.  
  15. double *holder;
  16. holder=scans.xyz_data;
  17.  
  18. int num_scans;
  19. bool flag_good;
  20. double xyz_array[3][Cycle];
  21. for (int i=0;i<Cycle;i++)
  22. {
  23. num_scans=0;
  24. flag_good=false;
  25. xyz_array[0][i]=0;
  26. xyz_array[1][i]=0;
  27. xyz_array[2][i]=0;
  28.  
  29. for (int j=0;j<scan_counter;j++)
  30. {
  31. if(scans.pos_good(j,i))
  32. {
  33. xyz_array[0][i]+=holder[j][0][i];
  34. xyz_array[1][i]+=holder[j][1][i];
  35. xyz_array[2][i]+=holder[j][2][i];
  36. num_scans++;
  37. flag_good=true;
  38. }
  39. else if (j==(scan_counter-1)&& flag_good==false)
  40. {
  41. xyz_array[0][i]=Bad;
  42. xyz_array[1][i]=Bad;
  43. xyz_array[2][i]=Bad;
  44. }
  45. }
  46. if(flag_good)
  47. {
  48. xyz_array[0][i]/=scan_counter;
  49. xyz_array[1][i]/=scan_counter;
  50. xyz_array[2][i]/=scan_counter;
  51. }
  52. }
  53. Label4->Caption=FloatToStr(xyz_array[scan_counter][509]);
  54. Label5->Caption=FloatToStr(xyz_array[scan_counter][509]);
  55. Label6->Caption=FloatToStr(xyz_array[scan_counter][509]);
  56. scan_counter++;
  57.  
  58. }

the error I get is this:
[C++ Error] Unit1.cpp(213): E2034 Cannot convert 'double ( *)[3][512]' to 'double *'
[C++ Error] Unit1.cpp(230): E2062 Invalid indirection


What am I doing wrong....I am not seeing something here that is probably obvious.

Thanks
Reply With Quote Quick reply to this message  
Join Date: May 2004
Posts: 12
Reputation: TJW is an unknown quantity at this point 
Solved Threads: 0
TJW TJW is offline Offline
Newbie Poster

Re: (reformatted) How to return Multi-Dimensional Arrays

 
0
  #6
May 31st, 2004
Do I need to use the new/delete? thanks
Reply With Quote Quick reply to this message  
Join Date: Dec 2007
Posts: 1
Reputation: ddavisso4 is an unknown quantity at this point 
Solved Threads: 0
ddavisso4 ddavisso4 is offline Offline
Newbie Poster

Re: (reformatted) How to return Multi-Dimensional Arrays

 
0
  #7
Dec 27th, 2007
I am somewhat new to C++ (all programming for that matter) but what I figured out is that if I simply pass the array that I want to be changed as a parameter to the function that would have returned the multidimensional array I can have that function change the data to whatever I need it to be. Probably not what you are looking for and definitely not great programming but I just thought I would throw it out there.

Ex.

int (*data)[9][9];

void *getData(int (*dataToBeChanged)[9][9]) {
dataToBeChanged = data;
}


As you can see above, 'data' is a pointer to a multidimensional array. After passing a multidimensional array of the same size to 'getData', the 'dataToBeChanged' referenced the same array.

Good luck! Looks like your doing some pretty cool stuff.
Reply With Quote Quick reply to this message  
Join Date: Feb 2009
Posts: 1
Reputation: Casperto is an unknown quantity at this point 
Solved Threads: 0
Casperto Casperto is offline Offline
Newbie Poster

Re: (reformatted) How to return Multi-Dimensional Arrays

 
0
  #8
Feb 1st, 2009
hey TJW iam doingthe exact same thing and i ran into the same problem so did you find any solution..
Reply With Quote Quick reply to this message  
Join Date: Dec 2004
Posts: 2,413
Reputation: Comatose is a jewel in the rough Comatose is a jewel in the rough Comatose is a jewel in the rough Comatose is a jewel in the rough 
Solved Threads: 211
Team Colleague
Comatose's Avatar
Comatose Comatose is offline Offline
Taboo Programmer

Re: (reformatted) How to return Multi-Dimensional Arrays

 
0
  #9
Feb 1st, 2009
*Grumbles*
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:


Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC