| | |
(reformatted) How to return Multi-Dimensional Arrays
Please support our C++ advertiser: Intel Parallel Studio Home
![]() |
•
•
Join Date: May 2004
Posts: 12
Reputation:
Solved Threads: 0
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]
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
(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]
C++ Syntax (Toggle Plain Text)
void scan_data::get_image_data(double data[3][Cycle]) { int num_scans; bool flag_good; for (int i=0; i<Cycle; i++) { num_scans=0; flag_good=false; data[0][i]=0; data[1][i]=0; data[2][i]=0; for (int j=0; j<current_scan; j++) { if (pos_good(j,i)) { data[0][i]+=xyz_data[j][0][i]; data[1][i]+=xyz_data[j][1][i]; data[2][i]+=xyz_data[j][2][i]; num_scans++; flag_good=true; } else if (j==(current_scan-1)&& flag_good==false) { //no good scans were available for this pixel location data[0][i]=Bad; data[1][i]=Bad; data[2][i]=Bad; } } if (flag_good) { //compute average of all the scans collected data[0][i]/=num_scans; data[1][i]/=num_scans; data[2][i]/=num_scans; } } return; }
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
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:
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:
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:
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:
The function FindMinToMkt is written such that adding new factories does not require any code changes, just a recompilation.
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:
C++ Syntax (Toggle Plain Text)
decl-specifiers dname [ constant-expressionopt ] ;
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:
C++ Syntax (Toggle Plain Text)
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:
C++ Syntax (Toggle Plain Text)
const int cMarkets = 4; // Declare a float that represents the transportation costs. double TransportCosts[][cMarkets] = { { 32.19, 47.29, 31.99, 19.11 }, { 11.29, 22.49, 33.47, 17.29 }, { 41.97, 22.09, 9.76, 22.55 } };
The technique of omitting the bounds specification for the first dimension of a multidimensioned array can also be used in function declarations as follows:
C++ Syntax (Toggle Plain Text)
#include <float.h> // Includes DBL_MAX. #include <iostream.h> const int cMkts = 4; // Declare a float that represents the transportation costs. double TransportCosts[][cMkts] = { { 32.19, 47.29, 31.99, 19.11 }, { 11.29, 22.49, 33.47, 17.29 }, { 41.97, 22.09, 9.76, 22.55 } }; // Calculate size of unspecified dimension. const int cFactories = sizeof TransportCosts / sizeof( double[cMkts] ); double FindMinToMkt( int Mkt, double TransportCosts[][cMkts], int cFacts ); void main( int argc, char *argv[] ) { double MinCost; MinCost = FindMinToMkt( *argv[1] - '0', TransportCosts, cFacts ); cout << "The minimum cost to Market " << argv[1] << " is: " << MinCost << "\n"; } double FindMinToMkt( int Mkt, double TransportCosts[][cMkts], int cFacts ) { double MinCost = DBL_MAX; for( int i = 0; i < cFacts; ++i ) MinCost = (MinCost < TransportCosts[i][Mkt]) ? MinCost : TransportCosts[i][Mkt]; return MinCost; }
Real Eyes Realize Real Lies
My Resume
My Resume
•
•
Join Date: May 2004
Posts: 12
Reputation:
Solved Threads: 0
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
Again thank you.
Tim
•
•
Join Date: May 2004
Posts: 53
Reputation:
Solved Threads: 1
•
•
•
•
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
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.
•
•
Join Date: May 2004
Posts: 12
Reputation:
Solved Threads: 0
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:
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
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:
C++ Syntax (Toggle Plain Text)
{ long scan_id,scan_length; double *pelem; if(scan_counter>9) scan_counter=0; css->get_scan(&scan_id,&scan_time,&scan_length,&data); // css_data->Add_Image_Data(data); scans.add_image(data); VariantClear(&data); VariantClear(&scan_time); double *holder; holder=scans.xyz_data; int num_scans; bool flag_good; double xyz_array[3][Cycle]; for (int i=0;i<Cycle;i++) { num_scans=0; flag_good=false; xyz_array[0][i]=0; xyz_array[1][i]=0; xyz_array[2][i]=0; for (int j=0;j<scan_counter;j++) { if(scans.pos_good(j,i)) { xyz_array[0][i]+=holder[j][0][i]; xyz_array[1][i]+=holder[j][1][i]; xyz_array[2][i]+=holder[j][2][i]; num_scans++; flag_good=true; } else if (j==(scan_counter-1)&& flag_good==false) { xyz_array[0][i]=Bad; xyz_array[1][i]=Bad; xyz_array[2][i]=Bad; } } if(flag_good) { xyz_array[0][i]/=scan_counter; xyz_array[1][i]/=scan_counter; xyz_array[2][i]/=scan_counter; } } Label4->Caption=FloatToStr(xyz_array[scan_counter][509]); Label5->Caption=FloatToStr(xyz_array[scan_counter][509]); Label6->Caption=FloatToStr(xyz_array[scan_counter][509]); scan_counter++; }
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
•
•
Join Date: Dec 2007
Posts: 1
Reputation:
Solved Threads: 0
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.
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.
![]() |
Similar Threads
- Matrix Multiplication using Multi-Dimensional Arrays (C++)
- compare multi-dimensional arrays and return they keys who's values are different (PHP)
- pointers and multi-dimensional arrays (C++)
- Multi-dimensional Arrays: (Python)
Other Threads in the C++ Forum
- Previous Thread: Logical error in finding Palindromes
- Next Thread: Help with string
| Thread Tools | Search this Thread |
api array based beginner binary bitmap c++ c/c++ calculator char char* class classes code coding compile compiler console conversion count database delete deploy desktop developer directshow dll download dynamiccharacterarray email encryption error file forms fstream function functions game givemetehcodez graph gui homeworkhelp homeworkhelper iamthwee ifstream input int integer java lib linux list loop looping loops map math matrix memory multiple news node number numbertoword output parameter pointer problem program programming project python random read recursion recursive reference return rpg sorting string strings struct temperature template templates text text-file tree url variable vector video visualstudio win32 windows winsock word wordfrequency wxwidgets






