-3

I am trying to build a code where I have to declare a large array in the heap. At the same time I will use the boost library to perform some matrix calculations (as can be seen in Fill a symmetric matrix using an array ).

My limitations here are two : I will deal with large arrays and matrices so I have to declare everything on the heap and I have to work with arrays and not with vectors.

However I am facing a rather trivial for many people problem... When filling the matrix, the last element doesn't get filled in correctly. So although I expect to get

[3,3]((0,1,3),(1,2,4),(3,4,5))

the output of the code is

[3,3]((0,1,3),(1,2,4),(3,4,2.6681e-315))

I am compiling this code in ROOT6. I don't think it's related to that, I am just mentioning it for completion.

A small sample of the code follows

#include <iterator>
#include <iostream>
#include <fstream>

#include </usr/include/boost/numeric/ublas/matrix.hpp>
#include </usr/include/boost/numeric/ublas/matrix_sparse.hpp>
#include </usr/include/boost/numeric/ublas/symmetric.hpp>
#include </usr/include/boost/numeric/ublas/io.hpp>

using namespace std;

int test_boost () {

    using namespace boost::numeric::ublas;
    symmetric_matrix<double, upper> m_sym1 (3, 3);

    float* filler = new float[6];
    for (int i = 0; i<6; ++i) filler[i] = i;
    float const* in1 = filler;

    for (size_t i = 0; i < m_sym1.size1(); ++ i)
        for (size_t j = 0; j <= i && in1 != &filler[5]; ++ j)
            m_sym1 (i, j) = *in1++;
    delete[] filler;
    std::cout << m_sym1 << std::endl;
    return 0;
}

Any idea on how to solve that?

Thanos
  • 594
  • 2
  • 7
  • 28
  • 4
    Why do you expect a pointer to have member functions? – scohe001 Feb 22 '18 at 17:01
  • 1
    Using `std::vector` or other STL container :-) – Jarod42 Feb 22 '18 at 17:01
  • @Jarod42 Thanks for your comment! I can't use `std::vector` because in the bigger project, I have to use some functions that don't use `std::vector` – Thanos Feb 22 '18 at 17:06
  • 2
    @Thanos That's most definitely not true. – Baum mit Augen Feb 22 '18 at 17:09
  • You can always grab the underlying array of a vector with `vector::data()`. For compile time constant sized arrays, you can use `std::array` which offers iterators, copy-assignment and other goodies. – patatahooligan Feb 22 '18 at 17:36
  • @patatahooligan : Thanks for your comment! Can I define an `std::array` on the heap using `new`? Finally I will have to deal with arrays and matrices that have sizes of `20000` and `20000 x 20000` respectively. – Thanos Feb 22 '18 at 17:48
  • You can, but you should steer clear of `new`. You can use an `std::unique_ptr>` if you absolutely want to enforce static size. `std::vector` also works but you have to make it `const` after filling it if you want to forbid modification. `std::unique_ptr` is the simplest solution if you're fine with a container that isn't size-aware and offers no iterators or helper functions. It has basically the same semantics as a `new`ed pointer except that it gets automatically deleted. – patatahooligan Feb 22 '18 at 18:17

2 Answers2

1

Arrays and pointers are not objects of class type, they don't have members. You already have a float *, it is filler.

float const* in1 = filler; // adding const is always allowed
Caleth
  • 52,200
  • 2
  • 44
  • 75
  • @Caleth : Thank you very much for your answer! The thing is since I am a novice, I don't quite understand what do you mean...and how to implement it in the code. – Thanos Feb 22 '18 at 17:14
  • Thank you very much once again! I have edited the question, to show why I need the `filler->begin()` address, which is to fill a symmetric matrix. In this case I think that `float const* in1 = filler;` or am I again wrong? – Thanos Feb 22 '18 at 17:25
1

I've manged to finally solve it by changing &filler[5] to &filler[6]. So a version that works is seen below

#include <iterator>
#include <iostream>
#include <fstream>

#include </usr/include/boost/numeric/ublas/matrix.hpp>
#include </usr/include/boost/numeric/ublas/matrix_sparse.hpp>
#include </usr/include/boost/numeric/ublas/symmetric.hpp>
#include </usr/include/boost/numeric/ublas/io.hpp>

using namespace std;

int test_boost () {

    using namespace boost::numeric::ublas;
    symmetric_matrix<double, upper> m_sym1 (3, 3);

    float* filler = new float[6];
    for (int i = 0; i<6; ++i) filler[i] = i;
    float const* in1 = filler;

    for (size_t i = 0; i < m_sym1.size1(); ++ i)
        for (size_t j = 0; j <= i && in1 != &filler[6]; ++ j)
            m_sym1 (i, j) = *in1++;
    delete[] filler;
    std::cout << m_sym1 << std::endl;
    return 0;
}

Running this code yields the following output

[3,3]((0,1,3),(1,2,4),(3,4,5))

Thanos
  • 594
  • 2
  • 7
  • 28