user7311356
user7311356

Reputation: 33

boost multiarray as class member is not filled

I'm trying to use boost to create a multidimensional array and I want said array to be a member of some class.

However I find two problems with it: 1 - I need to declare the size of the array with

boost::extents[2][2]

Everytime I want to use the array. Otherwise I get the following error:

a.out: /usr/include/boost/multi_array/base.hpp:136: Referenceboost::detail::multi_array::value_accessor_n<T, NumDims>::access(boost::type<Reference>, boost::detail::multi_array::value_accessor_n<T, NumDims>::index, TPtr, const size_type*, const index*, const index*) const [with Reference = boost::detail::multi_array::sub_array<double, 1ul>; TPtr = double*; T = double; long unsigned int NumDims = 2ul; boost::detail::multi_array::value_accessor_n<T, NumDims>::index = long int; boost::detail::multi_array::multi_array_base::size_type = long unsigned int]: Assertion `size_type(idx - index_bases[0]) < extents[0]' failed.

2 - Ok, maybe this is just part of how multidimensional arrays work in C++ with Boost, I'm going to write my code accepting every function "declares" the array. However, if I do this I find the array is empty.

Here's a snippet of code that reproduces this problem. During the "construction" of the class the array should be filled. However, the line

cout << "Result: " << testing.getArrayMember(0,1) << endl;

outputs "Result: 0".

#include <iostream>
#include "boost/multi_array.hpp"
typedef boost::multi_array<double, 2> dbl_array;

using namespace std;

class TestClass {
   public:
      dbl_array darray;
      TestClass(double x);
      void fillArray(double x);
      double  getArrayMember(int i, int j);
};

TestClass::TestClass(double x) {
   dbl_array darray(boost::extents[2][2]);
   cout << "Class constructor called" << endl;
   fillArray(x);
}

void TestClass::fillArray(double x) {
   cout << "Filling array" << endl;
   dbl_array darray(boost::extents[2][2]); // Without this line, the code     fails at runtime
   darray[0][0] = x;
   darray[1][0] = 2.0*x;
   darray[0][1] = 3.0*x;
   darray[1][1] = 4.0*x;
   cout << "Array filled" << endl;
}

double TestClass::getArrayMember(int i, int j) {
   dbl_array darray(boost::extents[2][2]); // Without this line, the code     fails at runtime
   return darray[i][j];
}

int main() {

   TestClass testing = TestClass(5.0);

   // The result is 0 in the end
   cout << "Result: " << testing.getArrayMember(0,1) << endl;
   return 0;
}

What am I doing wrong here?

Upvotes: 1

Views: 712

Answers (1)

Scarlehoff
Scarlehoff

Reputation: 89

Option 1 is to use an initialisation list:

TestClass::TestClass(double x) : darray(boost::extents[2][2]) {
   cout << "Class constructor called" << endl;
   fillArray(x);
}

Since otherwise the member of the class darray is created using the default constructor and not through your line

dbl_array darray(boost::extents[2][2]); 

as you believe.

This is the same answers as given in initialize boost::multi_array in a class

However, I want to add the following bit, which I think it is relevant in this situation:

It might be necessary for you to generate the array after performing some kind of operation in the constructor of your class. You can achieve this using "resize" after the array has been created by the default constructor.

Ie, instead of

TestClass::TestClass(double x) {
   dbl_array darray(boost::extents[2][2]);
   cout << "Class constructor called" << endl;
   fillArray(x); 
}

you could have

TestClass::TestClass(double x) {
   darray.resize(boost::extents[2][2]);
   cout << "Class constructor called" << endl;
   fillArray(x); 
}

Upvotes: 2

Related Questions