madalina
madalina

Reputation: 377

Returning a 2-dimensional array of doubles from function

I have this class in which at some point I am computing a array of two doubles:

double* QSweep::computeIntersection(double m1, double b1, double m2, double b2){
double* v=new double[2];

v[0]= (b2-b1)/(m1-m2);
v[1]= (m1*b2-m2*b1)/(m1-m2);

return v;
}

In another function of the class I am using this array to work with its values. Depending on the values transmitted as parameters I obtained several values for this array of two daoubles. And I want to retain all this values in a array of array of two doubles. I have tried some ways but I have bur error, segementation fault or all problems as this. Any idea is welcomed.

thank you in advance, madalina

Upvotes: 1

Views: 728

Answers (7)

madalina
madalina

Reputation: 377

thank you:), it worked with push_back the value obtained each time in a new vector of type

vector <double *>,

madalina

Upvotes: 0

Johannes Schaub - litb
Johannes Schaub - litb

Reputation: 507005

Given that what you have is an array of two doubles, i wouldn't doubt there is a need to raise that number up at some time. Like, if at some point you decide to add 3d functions too. I would therefor prefer to stay with an array. But there is no need to use a dynamic array. Use an array wrapped in a struct like boost::array:

boost::array<double, 2> QSweep::computeIntersection(
    double m1, double b1, double m2, double b2
) {
    boost::array<double, 2> array = { (b2-b1)/(m1-m2),  (m1*b2-m2*b1)/(m1-m2) };
    return array;
}

Then you can add it to a vector which will contain those:

typedef std::vector< boost::array<double, 2> > vec_of_2darray_t;
vec_of_2darray_t v;
v.push_back(computeIntersection(a, b, c, d));
// ...

This is probably the best you can get if you aim for both simplicity and extensibility.boost::array is a pretty small and simple struct. It basically amounts to

template<typename T, size_t N>
struct array { T data[N]; };

And several functions, of course, like operator[], begin() and end() and other stuff. But without constructors, so that you can initialize it like a normal array as we did above.

Upvotes: 0

Greg Domjan
Greg Domjan

Reputation: 14105

Your example doesn't include enough to be able to provide an answer to your question about why it's crashing.

The following example would ensure that there are no memory leaks from un-freed pointers, and keeps a similar structure.

typedef std::pair<double, double> Intersection;
typedef std::vector<Intersection> Plane;

Intersection QSweep::computeIntersection
  ( double m1
  , double b1
  , double m2
  , double b2) 
{
    return Intersection( (b2-b1)/(m1-m2), (m1*b2-m2*b1)/(m1-m2));
}

main() 
{
  Plane plane;
  while( input ){
    plane.push_back( Intersection( ... ) );
  }
}

There could be other ways of storing this, for instance as you are using double, you could use calloc and realloc to maintain one piece of memory the right size. (don't recommend it given your example so far)

Upvotes: 1

rlbond
rlbond

Reputation: 67779

Your other option is to change the signature:

void QSweep::computeIntersection(double m1, double b1, double m2, double b2, double& return_v0, double& return_v1)
{
    return_v0 = (b2-b1)/(m1-m2);
    return_v1 = (m1*b2-m2*b1)/(m1-m2);
}

Upvotes: 2

Aaron Hinni
Aaron Hinni

Reputation: 14716

Use a vector to maintain your history of doubles. If you continue to use an array of doubles, to hold onto them, do something like this:

std::vector<double*> history;
history.push_back(v);

Note, you will still need to delete the memory pointed to by each element when you are done with the vector (or individual vector elements). In order to get around this, use a pair to track your original array of doubles (if you are just using two), or a vector<double>.

Upvotes: 0

Dave Van den Eynde
Dave Van den Eynde

Reputation: 17415

Perhaps you should have a type called Intersection, which is done very quickly:

typedef std::pair<double, double> Intersection

Or perhaps there should be something more explicit in there, because the members of pair are "first" and "second" and perhaps you might want something more descriptive.

In any case, you'd rather return these things by value than returning a pointer to heap-allocated memory.

Upvotes: 1

Konrad Rudolph
Konrad Rudolph

Reputation: 545598

If they are always two values, wouldn't it be more logical (and more useful) to return a std::pair<double, double>? This might save a lot of pain, especially related to explicit memory management (since you're using new/delete):

std::pair<double, double> QSweep::computeIntersection(
    double m1, double b1, double m2, double b2
) {
    return std::make_pair( (b2-b1)/(m1-m2), (m1*b2-m2*b1)/(m1-m2));
}

Upvotes: 9

Related Questions