How to create 2d array c++? - c++

I need to create 2d array in c++.
I can't do it by int mas= new int[x][y]; or auto mas= new int[x][y];
I need to create an array dynamically like:
int x,y
auto mas= new int[x][y];//error - must be const.
Please help me.

int x,y;
x =3;
y = 5;
int ** mas = new int*[x];
for (int i=0;i<x;i++)
{
mas[i] = new int[y];
}
I think something like this.
Don't forget
for(int i=0;i<x;i++)
delete[] mas[i];
delete[] mas;
at the end.

The C++ tool for creating dynamically sized arrays is named std::vector. Vector is however one-dimensional, so to create a matrix a solution is to create a vector of vectors.
std::vector< std::vector<int> > mas(y, std::vector<int>(x));
It's not the most efficient solution because you pay for the ability to have each row of a different size. You you don't want to pay for this "feature" you have to write your own bidimensional matrix object. For example...
template<typename T>
struct Matrix
{
int rows, cols;
std::vector<T> data;
Matrix(int rows, int cols)
: rows(rows), cols(cols), data(rows*cols)
{ }
T& operator()(int row, int col)
{
return data[row*cols + col];
}
T operator()(int row, int col) const
{
return data[row*cols + col];
}
};
Then you can use it with
Matrix<int> mat(y, x);
for (int i=0; i<mat.rows; i++)
for (int j=0; j<mat.cols; j++)
mat(i, j) = (i == j) ? 1 : 0;

My advice would be to avoid the pain of multidimensional arrays in the first place and use a struct.
struct Point {
int x;
int y;
}
int points = 10;
Point myArray[points];
Then to access a value:
printf("x: %d, y: %d", myArray[2].x, myArray[2].y);
Depends on exactly what you're trying to achieve, though.

You can do the manipulations yourself.
int* mas = new int[x*y];
and access [i,j] by:
mas[i*y + j] = someInt;
otherInt = mas[i*y +j];

std::vector<std::vector<int> > mas(y, std::vector<int>(x));

Related

Initialise global array with respect to function input

I want to do something like:
int a[][]; // I know this code won't work, its to demonstrate what I want to do
void func(int n, int m){
a = int[n][m];
}
that is, initialise a global array whose size depends on function input. If this array was local, it would be a trivial case, but I don't know how to do this in the case shown above. Any help would be very useful!
You can create a matrix with std::vector:
std::vector<std::vector<int>> a;
void func(int n, int m) {
a.resize(n);
for(int i = 0; i < n; i++) {
a[i].resize(m);
}
}
Then you can access elements in the same way you do with int a[][]:
a[i][j] = number;
One way to achieve this is to encapsulate a flat std::vector in a Matrix class and use math to get an element with row and column as in this example:
template<typename T>
class Matrix {
private:
vector<T> vec;
//...
public:
T& get_value(size_t const row, size_t const col) {
return vec[row * col_count + col];
}
};
you can try this
int ** a; // is a pointer of two dimension
void func(int n, int m){
a = new int*[n]; //dynamic allocation global pointer a
for(int i = 0; i < n; i++)
a[i] = new int[m]();
}

Matrix - return and pass as parameter c++

I'm trying to use clear functions to do a matrix multiplication with random generated values. Therefore I'm hoping to use a function(mat_def) to generate the matrices and another function(mat_mul) to multiply them when the matrices are sent as parameters.
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
double mat_def(int n) //how to return the matrix
{
double a[n][n];
double f;
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
f= rand();
cout<<f ;
a[i][j]=f;
}
}
return 0;
}
double mat_mul( int n, double a[n][n], double b[n][n]) //how to send matrix as parameter
{
return 0;
}
int main()
{
/* initialize random seed: */
srand (time(NULL));
mat_def(10);
}
Here's a nice, standard C++ Matrix template for you.
Matrix.h
#include <vector>
class Matrix
{
class InnerM
{
private:
int ydim;
double* values;
public:
InnerM(int y) : ydim(y)
{
values = new double[y];
}
double& operator[](int y)
{
return values[y];
}
};
private:
int xdim;
int ydim;
std::vector<InnerM> inner;
public:
Matrix(int x, int y) : xdim(x), ydim(y), inner(xdim, InnerM(ydim))
{
}
InnerM& operator[](int x)
{
return inner[x];
}
};
All the memory leaks are there for you but you get the idea. From here you can handle the multiplication by overiding ::operator*() in the Matrix class.
I assume your problem is to define 2-D array and then pass it to mat_mul function to multiply the matrices. And the rest will be quite simple.
Defining the 2-D array(considering memory needs are known at run time):
int rows,cols;
cin >> rows;
cin >> cols;
int **arr = new int*[rows]; // rows X cols 2D-array
for(int i = 0; i < rows; ++i) {
arr[i] = new int[cols];
}
You can define another 2-D array exactly the same way with required rows and column.
now, Passing the 2-D array to function:
void mat_mul(int **arr1, int **arr2, int m, int n, int p, int q){
//define a 2-D array to store the result
//do the multiplication operation
//you could store the result in one of the two arrays
//so that you don't have to return it
//or else the return type should be modified to return the 2-D array
}
example:
void display(int **arr, int row, int col){
for (int i=0; i<row; i++){
for(int j=0;j<col; j++){
cout << arr[i][j] << '\t';
}
cout << endl;
}
}
Delete the memory if not required anymore with the following syntax:
for(int i=0; i<rows; i++){
delete[] array[i];
}
delete[] array;
hope this will be sufficient to get your work done!
there is already an answer on how to return a 2-D array on SO. Check the link below.
https://stackoverflow.com/a/8618617/8038009
Returning the raw allocation is a sucker bet. You need to manage all of the memory allocated yourself and pass it around with the matrix size parameters.
Why suffer? Use a matrix class
template<class Type>
class Matrix{
int rows;
int cols;
std::vector<type> data;
public:
Matrix(int row, int col):rows(row), cols(col), data(rows*cols)
{
// does nothing. All of the heavy lifting was in the initializer
}
// std::vector eliminates the need for destructor, assignment operators, and copy
//and move constructors.
//add a convenience method for easy access to the vector
type & operator()(size_t row, size_t col)
{
return data[row*cols+col];
}
type operator()(size_t row, size_t col) const
{
return data[row*cols+col];
}
};
Usage would be
Matrix<double> mat_mul(const Matrix<double> &a, const Matrix<double> &b)
{
Matrix<double> result;
// do multiplication
return result;
}
int main()
{
/* initialize random seed: */
srand (time(NULL));
Matrix<double> matA(10, 10);
matA(0,0) = 3.14; // sample assignment
matA(9,9) = 2.78;
double x = matA(0,0) * matA(9,9)
Matrix<double> matB(10, 10);
Matrix<double> matC = mat_mul(matA, matB) ;
}
More functionality, such as construction from an initializer list, can be added to the class to make your life easier. You can also specify an operator * overload for Matrix and use that in place of mat_mul if you chose. Read Operator overloading for more on that option.

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;
}

How to allocate a matrix in C++?

For a vector in C++, I have
class Vec
{
public:
int len;
double * vdata;
Vec();
Vec(Vec const & v)
{
cout<<"Vec copy constructor\n";
len = v.len;
vdata=new double[len];
for (int i=0;i<len;i++) vdata[i]=v.vdata[i];
};
I would greatly appreciate it if you could help me how to write an analogous code for a matrix. I am thinking something like this:
class Mat
{
public:
int nrows;
int ncols;
double * mdata;
Mat();
Mat(Mat const & m)
{
cout<<"Mat copy constructor\n";
nrows = m.nrows;
ncols = m.ncols;
But I don't know how to code the memory allocation for a matrix using the idea that first we put all the elements into a 1D array (row1 row2 ... rown) then we chop the array into rows and then chop each row into columns. Particularly, could you help me translate this idea into C++ language that is analogous to the following:
vdata=new double[len];
for (int i=0;i<len;i++) vdata[i]=v.vdata[i];
};
I am thinking of something like this:
double *data=new double[nrows*ncols];
for (int i=0;i<nrows;i++)
{
for (int j=0;j<ncols,j++){data(i,j)=m.mdata[i][j]};
};
But I am not sure about this part:
data(i,j)=m.mdata[i][j]
Also, I am supposed to use a pure virtual element indexing method: the (i,j) element of a Mat object m will be retrieved by m(i,j). I have to provide both const and non-const versions of this indexing operator.<-- May you show me how I could do this?
Thanks a lot.
Use as a single-dimensional array. You will notice that in practice, it's generally much simpler to use a 1d-array for such things.
class Matrix
{
public:
Matrix(unsigned int rows, unsigned int cols)
: _rows(rows)
, _cols(cols)
, _size(_rows*_cols)
, _components(new double[_size])
{
for(unsigned int i = 0; i < _size; ++i)
{
_components[i] = 0;
}
}
~Matrix()
{
delete[] _components;
}
double& operator()(unsigned int row, unsigned int col)
{
unsigned int index = row * _cols + col;
return _components[index];
}
private:
unsigned int _rows;
unsigned int _cols;
unsigned int _size;
double* _components;
};
However, if you want to actually use matrices and vectors, and not just implement them for learning, I would really advise you to use the Eigen library. It's free and open source and has great and easy-to-use vector and matrix classes.
While Eigen is great to use, if you want to look at source code of an existing implementation, it can be quite confusing for new programmers - it's very general and contains a lot of optimizations. A less complicated implementation of basic matrix and vector classes can be found in vmmlib.
Also you can use one standard vector to implement matrix but vector size will be nrows * ncols:
#include <vector>
class Mat {
public:
Mat(int rows, int cols):
nrows(rows),
ncols(cols),
elems(rows*cols,0)
{}
Mat(const Mat &m):
nrows(m.nrows),
ncols(m.ncols),
elems(m.elems.begin(), m.elems.end())
{}
double celem(int i,int j) const {
return elems[ncols*i + nrows*j];
}
double *pelem(int i,int j) {
return &elems[ncols*i + nrows*j];
}
private:
int nrows;
int ncols;
vector<double> elems;
};

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);