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


void scan_data::add_image(VARIANT & data_array) //collecting raw data
{
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] = pxyzelem->x;
xyz_data[current_scan][1] = pxyzelem->y;
xyz_data[current_scan][2] = pxyzelem->z;
}
++ pxyzelem;
}

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

current_scan++;
}


//storing newly converted data into an array

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]=0;
data[1]=0;
data[2]=0;
for (int j=0; j<current_scan; j++)
{
if (pos_good(j,i))
{
data[0]+=xyz_data[j][0];
data[1]+=xyz_data[j][1];
data[2]+=xyz_data[j][2];
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]=Bad;
data[1]=Bad;
data[2]=Bad;
}
}
if (flag_good)
{
//compute average of all the scans collected
data[0]/=num_scans;
data[1]/=num_scans;
data[2]/=num_scans;
}
}
return;
}


I need to return the results of member function get_image data. Everything I've tried isn't working

Thanks in advance

Dani AI

Generated

Short summary and diagnosis: a C-style array cannot be returned by value. The simplest, safest choices are (1) return a standard container (preferred), (2) have the caller pass a buffer to be filled, or (3) allocate on the heap and return a pointer (avoid unless necessary). The posted get_image_data appears to mix up indexing (the per-pixel values must be written to both dimensions, e.g. out[i][0], not out[0]), which is a common source of the failures seen by .

Modern, clean approach (C++11+): return a vector of 3-element points so lifetime is automatic and no manual memory management is needed.

#include <vector>
#include <array>

std::vector<std::array<double,3>> scan_data::get_image_data() const {
    std::vector<std::array<double,3>> out;
    out.reserve(Cycle);
    for (int i = 0; i < Cycle; ++i) {
        double sx=0, sy=0, sz=0; int n=0;
        for (int j = 0; j < current_scan; ++j)
            if (pos_good(j,i)) { sx += xyz_data[j][0]; sy += xyz_data[j][1]; sz += xyz_data[j][2]; ++n; }
        if (n == 0) out.push_back({Bad, Bad, Bad});
        else out.push_back({sx/n, sy/n, sz/n});
    }
    return out;
}

C++98 / older compilers (Borland C++ Builder 6): use std::vector<std::vector<double>> or a caller-supplied C array. Example caller-buffer signature:

void scan_data::get_image_data(double out[][3], int count);

Then fill out[i][0..2] for each i < count. That form decays to a pointer to arrays of 3 doubles and avoids returning stack pointers.

Notes and cautions: do not return pointers to local arrays. Prefer std::vector to avoid manual new[]/delete[]. If the API must be COM/Automation (VARIANT/SAFEARRAY), create and return a SAFEARRAY the caller owns (carefully follow COM ownership rules). Finally, ’s comma-style array[a,b] is not C++; C/C++ use array[row][col].

Recommended Answers

All 3 Replies

I'm not sure exactly, however in many other languages arrays have the following format:
array_name[deminsion1,deminsion2,deminsion3] = "value";

Please elaborate

In other languages a two deminsion array would look like:
array_name[4,19]
however your code has:
array_name[4][19]
I'm not sure if the upper array form is what c++ uses, however in 4 years I have only seen the upper one used... perhaps c++ uses the lower example though. Try it in the upper form & see if it works.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.