Dynamic Memory allocation during Transpose - c++

I am trying to calculate the transpose of a matrix that is not n by n.
The problem is I have to allocate new memory to each element being added, I do not have to delete the **array.
Code is something like that.
// initialize a 2-D array.
array = new int*[row];
for (int i=0; i<row; i++){
arr[i] = new int[col]();
}
Now I am considering just One case that suppose my matrix is 3*4. transpose of Matrix has dim 4*3.
I do the following code But it is giving "SEGMENTATION FAULT". The idea is i allocate a new memory to the element that would be added as a result of transpose.
Code is:
int r=col;
int c=row;
if (col<c){
arr = new int*[row];
for (int i=col; i<=c; i++){
arr[i] = new int[col](); // trying to allocate New Memory to elem.
}
It is giving error here.
Any Help. Also if there is any other method to solve this prolem , do suggest.

In your second code sample, you write over the array limits. arr is row elements long, counting from 0 to row - 1. In the for loop your index i goes from col to c which is equivalent to row and one element beyond the array. Correct code would be < instead of <=
for (int i=col; i < c; i++){
arr[i] = new int[col](); // trying to allocate New Memory to elem.
}
Apart from that, may I suggest you look at Wikipedia: Transpose, because in your second case you can use the the first code sample with just row and col switched.

Write a wrapper with accessor functions (e.g. operator(row,col) for matrices), and use a single-dimensional array of size rows*cols internally.
It makes things much easier, and keeps the data for this matrix together. This can have cache benefits for smaller matrices.
Here is an example, as requested in your comment. It's held very simple by purpose and does not use any templates. It uses a vector as internal storage. You can access the matrix elements using operator(..), e.g.
Matrix A(3,4);
// fill matrix
// you can access each element in a natural syntax as expected from math
int x = A(2,2);
A(2,2) = 3;
In addition, you probably should use exceptions instead of asserts to check for index overflow.
// matrix.h
#include <vector>
class Matrix
{
public:
Matrix(size_t rows, size_t cols);
int& operator()(size_t row, size_t col);
const int& operator()(size_t row, size_t col) const;
int& operator[](size_t index);
const int& operator[](size_t index) const;
Matrix get_transposed() const;
size_t compute_index(size_t row, size_t col) const;
void print();
private:
size_t _rows;
size_t _cols;
std::vector<int> _data;
}; // class Matrix
// matrix.cpp
#include "matrix.h"
#include <iostream>
#include <cassert>
Matrix::Matrix(size_t rows, size_t cols)
: _rows(rows)
, _cols(cols)
, _data(rows*cols, 0)
{
}
int& Matrix::operator()(size_t row, size_t col)
{
const size_t index = compute_index(row, col);
assert(index < _data.size());
return _data[index];
}
const int& Matrix::operator()(size_t row, size_t col) const
{
const size_t index = compute_index(row, col);
assert(index < _data.size());
return _data[index];
}
int& Matrix::operator[](size_t index)
{
return _data[index];
}
const int& Matrix::operator[](size_t index) const
{
return _data[index];
}
size_t
Matrix::compute_index(size_t row, size_t col) const
{
// here you should check that:
// row < rows
// col < cols
// and throw an exception if it's not
assert(row<_rows);
assert(col<_cols);
return row * _cols + col;
}
Matrix
Matrix::get_transposed() const
{
Matrix t(_cols,_rows);
for(size_t row = 0; row < _rows; ++row)
for(size_t col = 0; col < _cols; ++col)
{
t(col,row) = (*this)(row,col);
}
return t;
}

Related

Create a contiguous dynamic matrix

Arrays have this nice property of being contiguous blocks of memory. When using new to allocate memory for an array, it returns a pointer to a contiguous block of memory. However, if I allocate a matrix using new, like this:
#include <iostream> //std::cin
int main()
{
int n, m;
std::cin >> n >> m;
int** mat = new int*[n];
for (int i = 0; i < n; i++)
mat[i] = new int[m];
//use the matrix in some way
for (int i = 0; i < n; i++)
delete[] mat[i];
delete[] mat;
return 0;
}
This works, but mat doesn't point to a contiguous block of size n * m * sizeof(int). How can I do this in C++? I am just complying to the latest standard (that is C++17) and nothing else. I want an answer that doesn't involve STL containers or external libraries.
Please don't answer about C, as that is pretty easy to do in both C99 and C11 using variable-length arrays:
#include <stdio.h> //scanf
#include <stdlib.h> //malloc, free
int main()
{
int n, m;
scanf("%d %d", &n, &m);
//int mat[n][m]; VLA, but I want dynamic
int (*mat)[m] = malloc(n * sizeof *mat);
//use the matrix in some way;
free(mat);
return 0;
}
Here's what you were doing, almost exactly the same but without the non-contiguous memory:
#include <iostream> //std::cin
#include <memory>
int main()
{
int n, m;
std::cin >> n >> m;
auto matrix_data = std::make_unique<int[]>(n * m);
auto mat = std::make_unique<int[]>(n);
for(int i = 0; i < n; i++) { mat[i] = matrix_data.get() + i * m; }
// Use the matrix in some way
// No need to free anything - we're using smart pointers.
// No need to return 0 from main - that's the default
}
Notes:
This is still ugly code... you'd likely better create a proper matrix class, or better still - use somebody else's implementation.
It is better to follow #Someprogrammerdude's suggestion and use arithmetic rather than an array of pointers.
I kind of still don't know what particularly are you asking for. To store matrix elements in a contiguous location, simply allocate the memory for them as a one-dimensional dynamic array. The two basic options have been already discussed, either use a vector:
std::vector<int> mat(m * n);
or, if its memory overhead is significant for you, use a unique pointer:
auto mat = std::make_unique<int[]>(m * n);
Then, to access an element with i row index and j column index, simply use:
a_i_j = mat[i * n + j];
assuming m is the number of rows and n is the number of columns. This formula stores elements in so-called row-major order. If you need the column-major order, switch to:
a_i_j = mat[j * m + i];
Of course, whole approach would be much better encapsulated in a class with some getter operator mat(i, j);.
Here is a 2D matrix class that enables m[i][j] support and has a contiguous storage. It contains a minimalistic set of member functions to create and access elements.
It's a shame that the STD library does not provide such functionality. [i][j] element access is way less error prone than index arithmetics.
#include <cstddef>
#include <vector>
template <typename T>
class matrix
{
public:
using value_type = T;
private:
class row_view
{
public:
constexpr row_view(size_t length, value_type *begin)
: _length(length),
_begin(begin)
{}
value_type &operator[](size_t i) {
// TODO: check bounds
return *std::next(_begin, i);
}
const value_type &operator[](size_t i) const {
// TODO: check bounds
return *std::next(_begin, i);
}
size_t size() const {
return _length;
}
private:
size_t _length;
value_type *_begin;
};
public:
matrix(size_t rows, size_t cols, value_type &&defaultVal)
: _rows(rows),
_array(rows * cols, std::move(defaultVal))
{}
matrix(size_t rows, size_t cols)
: matrix(rows, cols, value_type{})
{}
size_t rows() const noexcept {
return _rows;
}
size_t cols() const noexcept {
return _array.size() / _rows;
}
auto operator[](size_t rowIndex) -> row_view{
const size_t offset = cols() * rowIndex;
return {cols(), &_array[offset]};
}
auto operator[](size_t rowIndex) const -> const row_view{
const size_t offset = cols() * rowIndex;
return {cols(), &_array[offset]};
}
private:
size_t _rows;
std::vector<value_type> _array;
};
https://godbolt.org/z/qoG6jGbh5

Create 2D array using size from parameters in C++

I am trying to create a simple 2D array with the size being the parameters passed by the method. In C# we would have something like this:
float[,] GenerateNoiseMap(int mapWidth, int mapHeight){
float noiseMap[,] = new float[mapWidth, mapHeight];
return noiseMap;
}
Any idea how I can create a 2D array and return it in C++?
So far the compiler gives me an error that the size has to be a constant value, and I want the values to be what the method parameters are
I like a simple wrapper around a 1D vector:
#include <vector>
class Matrix
{
private:
size_t rows, columns;
std::vector<double> matrix;
public:
Matrix(size_t numrows, size_t numcols) :
rows(numrows), columns(numcols), matrix(rows * columns)
{
}
double & operator()(size_t row, size_t column)
{
return matrix[row * columns + column]; // note 2D coordinates are flattened to 1D
}
double operator()(size_t row, size_t column) const
{
return matrix[row * columns + column];
}
size_t getRows() const
{
return rows;
}
size_t getColumns() const
{
return columns;
}
};
Documentation for std::vector
Usage:
Matrix noiseMap(mapWidth, mapHeight);
You cannot have a 2D C-like array with a dynamic size on both dimensions in C++. C# arrays look a bit like them, but they're not the same thing at all.
I recommend boost::multi_array for this:
#include <boost/multi_array.hpp>
boost::multi_array<float, 2> GenerateNoiseMap(int mapWidth, int mapHeight) {
return boost::multi_array<float, 2>{boost::extents[mapWidth][mapHeight]};
}
float ** create_matrix(size_t m, size_t n)
{
float ** answer = new float*[m];
for (size_t i =0; i < m; i++)
answer[i] = new float[n];
return answer;
}

template c++ to allocate dynamic matrix 2D

I'm trying to create a template to allocate dynamically an 2D matrix.
Usually what I do is:
float **Allocate_matrix_float (int m, int n)
{
float **v;
int i;
if (m < 1 || n < 1) {
printf ("** Invalid parameter **\n");
return (NULL);
}
v = (float **) calloc (m, sizeof(float *));
if (v == NULL) {
printf ("** Unsufficient memory **");
return (NULL);
}
for ( i = 0; i < m; i++ ) {
v[i] = (float*) calloc (n, sizeof(float));
if (v[i] == NULL) {
printf ("** Unsufficient memory **");
return (NULL);
}
}
return (v);
}
float **free_matrix_float (int m, int n, float **v)
{
int i;
if (v == NULL) return (NULL);
if (m < 1 || n < 1) {
printf ("** invalid parameter**\n");
return (v);
}
for (i=0; i<m; i++) free (v[i]);
free (v);
return (NULL);
}
However I'd like to create a template to allocate any type of 2D matrix. Can anyone help me?
The ideal would be something like:
template<typename T>
T**Allocate_matrix(int n, int m)
...
All of your allocation and deallocation code can be replaced by
std::vector<std::vector<float>> matrix(m, std::vector(n));
Seriously. It even deallocates itself when it goes out of scope, so you have almost no memory management issues.
#include <iostream>
#include <vector>
int main()
{
size_t m;
size_t n;
std::cin >> m >> n;
// floats initialized to 0.0
std::vector<std::vector<float>> fltmatrix(m, std::vector<float>(n));
// doubles initialized to 0.0
std::vector<std::vector<double>> dblmatrix(m, std::vector<double>(n));
// bools initialized to true
std::vector<std::vector<bool>> boolmatrix(m, std::vector<bool>(n), true);
// ints initialized to 42
std::vector<std::vector<int>> intmatrix(m, std::vector<int>(n, 42));
} <-- all vectors are released here.
Practically no effort required.
However, because each vector is it's own independent entity and you have m+1 vectors, you have m+1 different places in memory that your program needs to look to return a value. This can have a really bad impact on your programs performance as small matrices, say a 3x3, can't take full advantage of the CPU's caching and this can be very, very noticeable when crunching large numbers of matrices. If you don't care, stop reading and go with the simple vector of vector approach.
If you do care, wrap a 1D vector in a class:
#include <iostream>
#include <vector>
template<class TYPE>
class Matrix
{
private:
size_t rows, columns;
std::vector<TYPE> matrix;
public:
Matrix(size_t numrows, size_t numcols) :
rows(numrows), columns(numcols), matrix(rows * columns)
{
}
Matrix(size_t numrows, size_t numcols, TYPE init) :
rows(numrows), columns(numcols), matrix(rows * columns, init)
{
}
TYPE & operator()(size_t row, size_t column)
{
// check bounds here
return matrix[row * columns + column];
}
TYPE operator()(size_t row, size_t column) const
{
// check bounds here
return matrix[row * columns + column];
}
size_t getRows() const
{
return rows;
}
size_t getColumns() const
{
return columns;
}
friend std::ostream & operator<<(std::ostream & out, const Matrix & in)
{
for (int i = 0; i < in.getRows(); i++)
{
for (int j = 0; j < in.getColumns(); j++)
{
out << in(i, j) << ' ';
}
out << std::endl;
}
return out;
}
};
int main()
{
size_t m;
size_t n;
std::cin >> m >> n;
// floats initialized to 0.0
Matrix<float> fltmatrix(m, n);
std::cout << fltmatrix << std::endl;
// doubles initialized to 0.0
Matrix<double> dblmatrix(m, n);
std::cout << dblmatrix << std::endl;
// bools initialized to true
Matrix<bool> boolmatrix(m, n, true);
std::cout << boolmatrix << std::endl;
// ints initialized to 42
Matrix<int> intmatrix(m, n, 42);
std::cout << intmatrix << std::endl;
}
More effort, but should be faster. Profile your program to see if Matrix is right for you.
operator<< is included as an output convenience and as an example of how to access Matrix's cells.
And if you just have to use an array... Things get a lot uglier. For one thing, you will have to be Rule of Three (and possibly Rule of Five) compliant and pick up a bunch of extra functions that, frankly, you're probably not going to get right the first few times.
I'm not even sure I can get it right if I just bang one out, and I have a perfectly good alternative, so I'm not going to. What you can gain is a matrix that does not spend time initializing the matrix before use. If that is an issue (profile, profile, profile!) I'd call that a new question. The current question uses calloc so it doesn't look like OP is concerned.
As paddy mentions here using vector-of-vector is not practical, difficult to change and suffers from cache misses. As well as using bare pointers is impractical in terms of C++ which provides better tools like operator overloading.
Taking paddy's implementation as basis your 2d matrix can be implemented in the following way:
template <class T>
class SimpleMatrix
{
public:
SimpleMatrix( int rows, int cols, const T& initVal = T() )
: m_data( rows * cols, initVal )
, m_rows( rows )
, m_cols( cols )
{
}
// Direct vector access and indexing
operator const vector<T>& () const { return m_data; }
int Index( int row, int col ) const { return row * m_cols + col; }
// Get a single value
T & Value( int row, int col ) { return m_data[Index(row,col)]; }
const T & Value( int row, int col ) const { return m_data[Index(row,col)]; }
// Proxy structure to allow [][] indexing
struct Proxy
{
private:
friend class SimpleMatrix<T>;
SimpleMatrix<T>* m_matrix;
int m_row;
Proxy( SimpleMatrix<T>* m, int row ) : m_matrix(m), m_row(row) {}
public:
T & operator[] ( int col ) { return m_matrix->Value(m_row, col); }
const T & operator[] ( int col ) const { return m_matrix->Value(m_row, col); }
};
Proxy operator[]( int row ) { return Proxy(this, row); }
const Proxy operator[]( int row ) const { return Proxy(const_cast<SimpleMatrix<T>*>(this), row); }
private:
vector<T> m_data;
int m_rows;
int m_cols;
};
And use it in the following way:
SimpleMatrix<int> m(10, 2);
const SimpleMatrix<int>& cm = m;
m[1][1] = 1;
cout << cm[1][1];
This will also allow you to check the boundaries of the index.

c++ same code compiles/runs never in Visual Studio and sometimes in Qt Creator

I was making some of my c++ exercises when I noticed following problem.
The given code will not run/compile in Visual Studio 2013 or Qt Creator 5.4.1
giving the error:
invalid types 'double[int]' for array subscript
test[0][0] = 2;
^
However when you first change the 16th (and 17th) line in the header file from
double &operator[]; to double operator[] and make the same changes in the source files -> then compile this (while getting multiple errors) -> and lastly changing it back to the original double &operator[];. Then in Qt Creator 5.4.1 it will compile and it will run while giving the expected results.
Edit: This does not always work, however changing it to double *operator[] instead of double operator[] will always reproduce the problem.
Why is this happening?
matrix.h
#ifndef MATRIX_H
#define MATRIX_H
#include <iostream>
using namespace std;
class Matrix
{
private:
double** m_elements;
int m_rows;
int m_columns;
public:
Matrix(int rows = 1, int columns = 1);
double &operator[](int index);
const double &operator[](int index) const;
friend ostream &operator<<(ostream &ostr, Matrix matrix);
};
#endif // MATRIX_H
matrix.cpp
#include "matrix.h"
Matrix::Matrix(int rows, int columns)
{
m_rows = rows;
m_columns = columns;
m_elements = new double*[rows];
for(int i=0; i<rows; i++)
{
m_elements[i] = new double[columns];
for(int j=0; j<columns; j++)
m_elements[i][j] = 0;
}
}
double &Matrix::operator[](int index)
{
return *(m_elements[index]);
}
const double &Matrix::operator[](int index) const
{
return *(m_elements[index]);
}
ostream &operator<<(ostream &ostr, Matrix matrix)
{
for(int i=0; i<matrix.m_rows; i++)
{
for(int j=0; j<matrix.m_columns; j++)
{
ostr << matrix.m_elements[i][j] << " ";
}
ostr << "\n";
}
return ostr;
}
main
#include <iostream>
#include "matrix.h"
using namespace std;
int main()
{
Matrix test(4,4);
test[0][0] = 2;
cout << test;
return 0;
}
double &Matrix::operator[](int index)
{
return *(m_elements[index]);
}
Will return a reference to the first element in the column rather than the column. So calling test[0][0] = 2; tries to apply the [] operator to a double, not an array of double.
Quick solution:
double * & Matrix::operator[](size_t index)
{
return m_elements[index];
}
This returns a reference to a pointer (read on to find out why I bother with the reference) and you can use [] on the returned pointer to get to the data element.
But...
There are better ways to do this.
Use std::vector, if possible, instead of the dynamic array.
std::vector<std::vector<double> > m_elements(m_rows, std::vector<double>(m_columns, 0.0));
This will solve a lot of potential problems and does the initializing of the matrix to 0 in one shot. It won't solve the [][] indexing though. That will still take a bit of work.
The simplest and safest way to do the indexing is to not use the [] operator at all. Instead define a new method. This way you have total control over what is exposed, and the input can be completely tested for validity before running out of bounds.
double &Matrix::at(size_t row, size_t column)
{
// optional overrun defence if desired
if (row < m_rows || column < m_columns)
{
return m_elements[row][column];
}
throw std::out_of_range("Matrix indices out of range");
}
double Matrix::at(size_t row, size_t column) const
{
// put overrun defence here if desired
return m_elements[row][column];
}
matrix.at(2,3) = 2;
constmatrix.at(2,3) = 2; // bad lvalue compiler error
Note the use of size_t in place of int. size_t is unsigned and removes the need to validity check for negative numbers. You can't have a negative array index, so why allow the possibility?
It is also worth noting that this approach makes it easy to define storage for your matrix as a 1 dimensional array like this:
std::vector<double> m_elements(m_rows * m_columns, 0.0);
or if you have to use an array
double m_elements = new double[m_rows* m_columns];
and access it like this:
double &Matrix::at(size_t row, size_t column)
{
return m_elements[row * m_rows + column];
}
Why? A number of good reasons. Easier to create, maintain and clean up one object than m_rows +1 is a good enough reason for me. Another excellent reason is locality. The whole matrix is guaranteed to be in one contiguous block, not one array here, another there, and yet another in the RAM equivalent of the bottom of the Marianas Trench. The odds of cache hits (and thus performance) go way up.
If you prefer the look and feel of an array, an operator() overload comes quite close.
double &Matrix::operator()(size_t row, size_t column)
{
return m_elements[row][column];
}
double Matrix::operator()(size_t row, size_t column) const
{
return m_elements[row][column];
}
matrix(2,3) = 2;
If you must have [][]
The suggested form of an [] operator returns a reference to the indexed data, in this case a vector or a pointer to a row array.
std::vector<double> & Matrix::operator[](size_t index)
{
return m_elements[index];
}
or
double * & Matrix::operator[](size_t index)
The array and vector internals are identical.
Caveat: This allows the user to get up to all sorts of trouble with that returned vector or pointer reference. Consider matrix[0].clear(); or matrix[0] = NULL; for example.
double * Matrix::operator[](size_t index)
will prevent most abuse by returning a copy of the pointer. Unfortunately this cannot be done to protect the vector because a copy of the vector will be a completely different vector with copies of the source's contents. Updating it and expecting persistence would be futile. The vector would have to be hidden from the user inside a wrapper class, and this is rapidly becoming too much work.
In addition, returning the copy or a wrapper will also block legitimate uses of a reference and violates the Law of Least Surprise: The Matrix [] operator does not work the same as other [] operators and may result in unexpected behaviour if an unsuspecting coder uses it as a regular [] operator.
My opinion is return the unprotected references, and if whoever is using the Matrix class wants to shoot themselves in the head... Well, you can only do so much. If you have to protect the user, use the at method or operator() approach described above.
Const [] operators are similar for the vector
std::vector<double> const & Matrix::operator[](size_t index) const
but different for the array because both the pointer and the values pointed at should be const
double const * const & Matrix::operator[](size_t index) const
My suggested implementation:
Matrix.h
#ifndef MATRIX_H
#define MATRIX_H
#include <iostream>
#include <vector>
// note that the using namespace std; is gone. One should never put it in the header
// and one should also think hard about putting it in the implementation file
class Matrix
{
private:
std::vector<double> m_elements;
size_t m_rows;
size_t m_columns;
public:
Matrix(int rows = 1, int columns = 1);
double &operator()(size_t row, size_t column);
double operator()(size_t row, size_t column) const;
friend std::ostream &operator<<(std::ostream &ostr, const Matrix & matrix);
};
#endif // MATRIX_H
Matrix.cpp
#include <stdexcept>
#include "Matrix.h"
Matrix::Matrix(int rows, int columns):
m_elements(rows * columns, 0.0),
m_rows(rows),
m_columns(columns)
{
}
std::ostream &operator<<(std::ostream &ostr, const Matrix &matrix)
{
for(size_t i=0; i<matrix.m_rows; i++)
{
for(size_t j=0; j<matrix.m_columns; j++)
{
ostr << matrix(i,j) << " ";
}
ostr << std::endl;
}
return ostr;
}
double &Matrix::operator()(size_t row, size_t column)
{
if (row < m_rows && column < m_columns)
{
return m_elements[row * m_rows + column];
}
throw std::out_of_range("Matrix indices out of range");
}
double Matrix::operator()(size_t row, size_t column) const
{
if (row < m_rows && column < m_columns)
{
return m_elements[row * m_rows + column];
}
throw std::out_of_range("Matrix indices out of range");
}
Just Because of the Meaning of the Return.
When You return Reference &, you could change it as you wanna, like test[2][2] = 2;Because it will make mean back to the source it had ever refer to
When You return By value, It just a temporary Object which will be destroyed after using, that means, You Could Not Change It !

Declare a multidimentional array without the size

I want to declare an array of arrays or multidimensional array without knowing the size.
I want to do something similar to what I did in this cases with simple arrays:
int *array;
cin >> size;
array = new int[size];
Maybe I can loop to initialize a pointer of pointers like this:
int **array;
cin >> rows >> col;
array = new *int[rows]
for (int i = 0; i < rows; ++i)
array[i] = new int[col];
But I would prefer to not do this if a better solution exists.
Why not use std::vector?
std::vector<std::vector<int> > array;
If you don't want to use an array of pointers, you could use one large array that you allocate dynamically after you get the size and access it as an array of rows.
int rows = 10;
int columns = 20;
int* array = new int[rows * columns];
for (int count = 0; count < rows; count++)
{
int* row = &array[count * columns];
for (int inner_count = 0; inner_count < columns; inner_count++)
{
int* element = &row[inner_count];
//do something
}
}
delete [] array;
You're pretty much going to have to go with the loop version. You can make one slight improvement, which is to allocate one big block and then build your own int* index into it:
int **array;
int *storage;
cin >> rows >> col;
array = new *int[rows];
storage = new int[rows*col];
for (int i = 0; i < rows; ++i)
array[i] = storage + col * i;
This has the nice property that you can still use array[i][j] syntax for accessing the array.
You could use a single std::vector to contain the entire two dimensional array and wrap it in a class to hide the details. Here's an example, it uses a data( row, col ) member function that returns a reference to the element at row and col. I included an example 2 dimensional matrix of int where each entry in the array is initialized to the product of its row and col. When an instance of this class goes out of scope, the default destructor will get called and release the memory, that way you don't have to remember to call delete[] to release the memory. All elements of the matrix will be contiguous in memory, this is cache friendly and should give you good performance.
#include <iostream>
#include <vector>
#include <stdexcept>
template <typename T>
class matrix {
std::vector<T> data_;
public:
size_t const rows_;
size_t const cols_;
matrix(size_t rows, size_t cols)
: rows_(rows)
, cols_(cols)
, data_( rows * cols )
{}
T& data( size_t row, size_t col ) {
if (row > rows_ || col > cols_) throw std::out_of_range("matrix");
return data_[ row * cols_ + col ];
}
};
int main( int argc, char** argv )
{
matrix<int> array(100,100);
for(size_t r=0; r < array.rows_; ++r) {
for(size_t c=0; c < array.cols_; ++c) {
array.data(r,c) = r * c;
}
}
std::cout << "8 x 7 = " << array.data(8,7) << std::endl;
return 0; // array goes out of scope here, memory released automatically
}
When you run this you will get
8 x 7 = 56
If you care, you can have a little bit more convenience by have a helper
template <typename T>
struct C3DArray
{
vector<vector<vector<T>>> m;
C3DArray(int size_x, int size_y, int size_z)
: m(make(T(), size_z, size_y, size_x))
{ }
template <typename U> static std::vector<U> make(U v, size_t n) {
return { n, std::move(v) };
}
template <typename U, typename... Dim> static auto make(U v, size_t n, Dim... other)
-> std::vector<decltype(make(v, other...))> {
return { n, make(v, other...) };
}
};
This uses variadics. Use it like this:
C3DArray<int> arr(3,4,20);