Initializing Dynamic 2d array in c++ - c++

I have created the class and first constructor, but I don't know how to initialize 2d array to ref as asked in 2, need to do this using dynamic memory allocation.
Create a class named matrix having followed private members:
• int **p;
• int rows;
• int cols;
The class should have the following member functions:
matrix () initializes the 2d array to zero. Assume rows = 2 and cols = 2
matrix (int **ref, int r, int c) initializes the 2d array to ref
MY CODE:
class Matrix
{
private:
int **p;
int rows;
int cols;
public:
// CONSTRUCTORS
Matrix()
{
rows = 2;
cols = 2;
p = new int*[2];
// initialize the array with 2x2 size
for (int i=0; i<2; i++)
{
p[i] = new int[2];
}
// taking input for the array
for (int i=0; i<2; i++)
{
for (int j=0; j<2; j++)
{
p[i][j] = 0;
}
}
};
Matrix(int **ref, int r, int c)
{
rows = r;
cols = c;
p = new int*[rows];
// initialize the array with 2x2 size
for (int i=0; i<rows; i++)
{
p[i] = new int[cols];
}
// taking input for the array
for (int i=0; i<rows; i++)
{
for (int j=0; j<cols; j++)
{
p[i][j] = **ref;
}
}
}
friend ostream& operator << (ostream& output, Matrix& obj)
{
output << obj.rows;
cout << " = ROWS" << endl;
output << obj.cols;
cout << " = columns" << endl;
for (int i=0; i<obj.rows; i++)
{
for(int j=0; j<obj.cols;j++)
{
cout << obj.p[i][j] << " " ;
}
cout << endl;
}
return output;
}
};
int main()
{
Matrix a;
cout << a << endl;
return 0;
}

It seems p[i][j] = **ref; should be p[i][j] = ref[i][j];.
Also you should follow The Rule of Three. In other words, you should declare copy constructor and assignment operator to handle object (including pointers) copying properly.

Related

how to sum a matrice with a number in c++ using operator overloading? [duplicate]

This question already has answers here:
What is The Rule of Three?
(8 answers)
Closed 2 years ago.
I am trying to write a matrice class in c++ with a overloaded + operator that is a friend function for summing a matrix with a number, ie sum every element of the matrice with the number.
for example:-
2+ |1|2| = |3|4|
|2|1| |4|3|
main.cpp :-
#include <iostream>
using namespace std;
class matrice {
int** a;
int rows, columns, i, j;
public:
matrice() {}
matrice(matrice& A) { //copy constructor for deep copying the result of 2+A into C
rows = A.rows;
columns = A.columns;
a = new int* [rows];
for (i = 0; i < rows; i++) {
a[i] = new int[columns];
*a[i] = 0;
}
for (i = 0; i < rows; i++) {
for (j = 0; j < columns; j++) {
a[i][j] = A.a[i][j];
}
}
}
matrice(int m, int n) {
rows = m;
columns = n;
a = new int* [rows];
for (i = 0; i < rows; i++) {
a[i] = new int[columns];
*a[i] = 0;
}
}
~matrice() {
delete[] a;
}
void insert(int p, int q, int value) {
a[p][q] = value;
}
void print() {
for (i = 0; i < rows; i++) {
cout << "\n";
for (j = 0; j < columns; j++) {
cout << a[i][j] << " ";
}
}
}
friend matrice operator+(int k, matrice& A);
friend matrice operator+(matrice& A, int k);
};
matrice operator+(int k, matrice& A) { //for performing 2+A
matrice temp(A.rows, A.columns);
for (int i = 0; i < A.rows; i++) {
for (int j = 0; j < A.columns; j++) {
temp.a[i][j] = A.a[i][j] + k;
}
}
return temp;
}
matrice operator+(matrice& A, int k) { //for performing A+2
matrice temp(A.rows, A.columns);
for (int i = 0; i < A.rows; i++) {
for (int j = 0; j < A.columns; j++) {
temp.a[i][j] = A.a[i][j] + k;
}
}
return temp;
}
int main() {
int i, j, m, n, value;
cout << "\nEnter order of A matrice:";
cin >> m >> n;
matrice A(m, n);
cout << "\nEnter the matrice:";
for (i = 0; i < m; i++) {
cout << "\nEnter row " << i + 1 << " : ";
for (j = 0; j < n; j++) {
cin >> value;
A.insert(i, j, value);
}
}
cout << "\nThe entered matrice is :";
A.print();
cout << "\n\n";
cout << "\nEnter order of B matrice:";
cin >> m >> n;
matrice B(m, n);
cout << "\nEnter the matrice:";
for (i = 0; i < m; i++) {
cout << "\nEnter row " << i + 1 << " : ";
for (j = 0; j < n; j++) {
cin >> value;
B.insert(i, j, value);
}
}
cout << "\nThe entered matrice is :";
B.print();
cout << "\n\ntesting 2+A";
matrice C; //Everything upto here is fine
C = A + 2; // C.a is pointing to unreadable memory because of destruction after doing A+2
C.print(); // so access violation error
}
The problem is that the destructor of C is called after invoking the copy constructor which causes the double pointer a in C to be deleted. So when C.print() is called An Access violation reading location 0xDDDDDDDD exception is thrown.
I can't find out why C's destructor is called.
The rule of 5 says that if you manually handle allocations, you should have an explicit (or explicitely deleted):
copy constructor
copy assignment operator
move constructor
move assignement operator
destructor
You might omit the ones that you are sure that you code will never use, but it is highly dangerous.
Anyway correct allocation/de-allocation handling is complex and requires very cautious code. For example the correct declaration for a copy ctor should be matrice(const matrice& A), and comments already warned you of memory leaks.
So my advice is:
if you want to learn about manual allocation management, follow best practices: rule of 5 an copy/swap idiom to avoid caveats
if you just want working code, replace 1D dynamic arrays with vectors and let the standard library handle the corner cases

I don't understand what's wrong

Here is a my own Matrix class:
class Matrix {
private:
int row; // rows
int col; // columns
double** matrix; // pointer to this matrix
public:
Matrix();
Matrix(int row, int col);//creating matrix based on two params
Matrix(double** matx, int row, int col); //Here is a problem
Matrix(Matrix& N);//copy constructor
~Matrix();
//first, second and fourth constructors works good
int getRow();
int getCol();
void changeSize(int row, int col);
void randValues();
void writeValues();
};
Here is a body of constructor, This constructor need take a exists matrix as parameter and create a new one based on the matrix provided (it's NOT a copy constructor)
Matrix::Matrix(double** matx, int row, int col){
//allocated memory for new matrix
matrix = new double*[row];
for (int i = 0; i < row; i++){
matrix[i] = new double[col];
}
// //copy values to new matrix
for(int i=0; i<row; i++)
{
for(int k = 0; k < col; k++)
{
matrix[i][k] = matx[i][k];
}
}
};
int main(){
double** test = new double *[5];
for(int i = 0; i < 5; i++){
test[i] = new double;
}
for(int i = 0; i < 5; i++){
for(int k = 0; k < 5; k++){
test[i][k] = 0.11;
cout << test[i][k] << " ";//just for make me sure if is ok
}
cout << "\n";
}
Matrix *matx = new Matrix(test,5,5);
matx->writeValues();
return 0;
}
And when I run a program they write on console lots of zeros values and few garbage and of the end is: Process returned -1073741819 (0xC0000005) execution time : 2.162 s

Arbitrary matrix dimension in matrix class

The task is as follows: Describe the class "matrix of numbers" with component data: the dimensions of the matrix, a pointer to the elements. Overload operations: << (matrix output to the screen), + (addition of matrices), unary ¬– (change the sign of each element), / = (divide each element by a number). I performed it, and performed it correctly, but you need to set the matrix dimension from the keyboard, and as you can see, it is set in advance for me [3] [3]. It sounds pretty simple, but something I'm really dumb. Thanks in advance for your help. Here is the code:
#include "pch.h"
#include <iostream>
using namespace std;
class Matrix
{
public:
Matrix()
{
int Table[3][3];
}
int Table[3][3];
void Create()
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
Table[i][j] = 10;
}
};
ostream& operator <<(ostream& t, Matrix a)
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
t << a.Table[i][j] << " ";
t << "\n";
}
return t;
}
Matrix& operator /=(Matrix& a, int num)
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
a.Table[i][j] /= num;
return a;
}
Matrix& operator -(Matrix& a, int empty)
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
a.Table[i][j] = -a.Table[i][j];
return a;
}
Matrix& operator +(Matrix& a, Matrix b)
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
a.Table[i][j] += b.Table[i][j];
return a;
}
int main()
{
int u;
setlocale(LC_ALL, "Russian");
Matrix Example;
Example.Create();
Matrix Example1;
Example1.Create();
cout << Example;
cout << Example1;
cout << "Сумма матриц: "<<endl;
cout << Example + Example1;
Example - 1;
Example1 - 1;
cout<< Example + Example1;
cout << "На сколько вы хотите её поделить?\n";
cin >> u;
Example /= u;
Example1 /= u;
cout << Example;
cout << Example1;
}`
You need to dynamically create the matrix.
In order to this you need to use pointers(*). Change int table[3][3]
double table**;
An example of how it could be implemented (note that I use matrix instead of table)
class Matrix {
private:
double** matrix;
int col;
int row;
public:
Matrix(){};
void Create(int row, int col);
};
void Matrix::Create(int row_, int col_){
double val = 0.0;
col = col_; // initalize private members
row = row_;
matrix = new double*[row]; // Create a new array of size row_
for(int i = 0; i < row; i++)
{
matrix[i] = new double[col]; // Create new cols of size col (inside array of row)
}
for(int i = 0; i < row; i++)
{
for(int j = 0; j < col; j++)
{
matrix[i][j] = val;
val = val + 1.0;
}
}
}
I tried to reuse your design for simplicity, but I really suggest that you try to specify the dimensions of the matrix in a constructor instead and maybe even construct the matrix in it as well.
Something like this:
Matrix(int row_, int col_) : row(row_), col(col_) {*/ create matrix here /*};
You can skip the "create matrix here" part and use your own Create() if you want to.
You need dynamic memory allocation for that. I won't fiddle around with pointers (new / delete) unless you are explicitly told to. As a beginner you should probably use the standard template library (STL) tools:
#include <vector> and use std::vector<std::vector<int>> Table instead of int Table[3][3]. Then write a constructor like this:
Matrix(std::size_t rows, std::size_t cols)
{
Table.resize(rows);
for (unsigned int i = 0; i < Table.size(); ++i)
Table[i].resize(cols);
}
You can additionally store the dimension of the matrix, but there is no need to do it since you can get the information from the vectors. Replace the hardcoded dimensions in all loops by the corresponding dynamic sizes (stored or extracted from the vectors). For example:
Matrix& operator +(Matrix& a, Matrix b)
{
unsigned int rows = a.Table.size();
unsigned int cols = a.Table[0].size();
for (unsigned int i = 0; i < rows; i++)
for (unsigned int j = 0; j < cols; j++)
a.Table[i][j] += b.Table[i][j];
return a;
}
However, this vector of vectors is not really effective. Better would be a single vector but I guess for a beginner it is okay.
Greetings

Class matrix addition

I have a program that is suppose to add together two matrices but when it gets to the add part in the main it just gets stuck and does nothing. I have messed with this for quite some time but to no avail. Any help or recommendations would be appreciated.
#include <iostream>
using namespace std;
class matrix
{
private:
int **p, m, n;
public:
matrix(int row, int col)
{
m = row;
n = col;
p = new int*[m];
for (int i = 0; i < m; i++)
p[i] = new int[n];
}
~matrix()
{
for (int i = 0; i < m; i++)
delete p[i];
delete p;
}
void fill()
{
cout<<"Enter the matrix elements:";
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
cin >> p[i][j];
}
}
}
void display()
{
cout <<"The matrix is:";
for(int i = 0; i < m; i++)
{
cout << endl;
for(int j = 0; j < n; j++)
{
cout << p[i][j] <<" ";
}
}
cout << endl;
}
matrix operator +(matrix m2)
{
matrix T(m, n);
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
T.p[i][j] = p[i][j] + m2.p[i][j];
}
}
return T;
}
matrix operator =(matrix eq)
{
m = eq.m;
n = eq.n;
p = eq.p;
return *this;
}
friend matrix operator *(matrix, matrix);
};
matrix operator *(matrix a , matrix b)
{
matrix B(1,1);
if(a.n == b.m)
{
matrix T(a.m, b.n);
for(int i = 0; i < a.m; i++)
{
for(int k = 0; k < b.n; k++)
{
T.p[i][k] = 0;
for(int j = 0; j < a.n; j++)
{
T.p[i][k]+= a.p[i][j] * b.p[j][k];
}
}
}
B = T;
}
return B;
}
int main()
{
matrix a(3,3), b(3,3);
a.fill();
a.display();
b.fill();
b.display();
cout << "addition of a and b\n";
b = b + a;
b.display();
cout << "multiplication of a and b\n";
b = (a * b);
b.display();
}
Your program is violating the rule of big three: it has a destructor but no assignment operator and no copy constructor. It keeps the data using raw pointers, but it's not managing proper ownership with copies are done and assignments are performed.
When your matrix class is copied and assigned your program is entering the Undefined Behavior territory so anything can happen. In this code copy construction is done implicitly when passing a matrix parameter by value, and assignment is done explicitly in main.

Pointer-to-pointer dynamic two-dimensional array

First timer on this website, so here goes..
I'm a newbie to C++ and I'm currently working through the book "Data structures using C++ 2nd ed, of D.S. Malik".
In the book Malik offers two ways of creating a dynamic two-dimensional array.
In the first method, you declare a variable to be an array of pointers, where each pointer is of type integer. ex.
int *board[4];
..and then use a for-loop to create the 'columns' while using the array of pointers as 'rows'.
The second method, you use a pointer to a pointer.
int **board;
board = new int* [10];
etc.
My question is this: which is the better method? The ** method is easier for me to visualize, but the first method can be used in much the same way. Both ways can be used to make dynamic 2-d arrays.
Edit: Wasn't clear enough with the above post. Here's some code I tried:
int row, col;
cout << "Enter row size:";
cin >> row;
cout << "\ncol:";
cin >> col;
int *p_board[row];
for (int i=0; i < row; i++)
p_board[i] = new int[col];
for (int i=0; i < row; i++)
{
for (int j=0; j < col; j++)
{
p_board[i][j] = j;
cout << p_board[i][j] << " ";
}
cout << endl;
}
cout << endl << endl;
int **p_p_board;
p_p_board = new int* [row];
for (int i=0; i < row; i++)
p_p_board[i] = new int[col];
for (int i=0; i < row; i++)
{
for (int j=0; j < col; j++)
{
p_p_board[i][j] = j;
cout << p_p_board[i][j] << " ";
}
cout << endl;
}
The first method cannot be used to create dynamic 2D arrays because by doing:
int *board[4];
you essentially allocated an array of 4 pointers to int on stack. Therefore, if you now populate each of these 4 pointers with a dynamic array:
for (int i = 0; i < 4; ++i) {
board[i] = new int[10];
}
what you end-up with is a 2D array with static number of rows (in this case 4) and dynamic number of columns (in this case 10). So it is not fully dynamic because when you allocate an array on stack you should specify a constant size, i.e. known at compile-time. Dynamic array is called dynamic because its size is not necessary to be known at compile-time, but can rather be determined by some variable in runtime.
Once again, when you do:
int *board[4];
or:
const int x = 4; // <--- `const` qualifier is absolutely needed in this case!
int *board[x];
you supply a constant known at compile-time (in this case 4 or x) so that compiler can now pre-allocate this memory for your array, and when your program is loaded into the memory it would already have this amount of memory for the board array, that's why it is called static, i.e. because the size is hard-coded and cannot be changed dynamically (in runtime).
On the other hand, when you do:
int **board;
board = new int*[10];
or:
int x = 10; // <--- Notice that it does not have to be `const` anymore!
int **board;
board = new int*[x];
the compiler does not know how much memory board array will require, and therefore it does not pre-allocate anything. But when you start your program, the size of array would be determined by the value of x variable (in runtime) and the corresponding space for board array would be allocated on so-called heap - the area of memory where all programs running on your computer can allocate unknown beforehand (at compile-time) amounts memory for personal usage.
As a result, to truly create dynamic 2D array you have to go with the second method:
int **board;
board = new int*[10]; // dynamic array (size 10) of pointers to int
for (int i = 0; i < 10; ++i) {
board[i] = new int[10];
// each i-th pointer is now pointing to dynamic array (size 10) of actual int values
}
We've just created an square 2D array with 10 by 10 dimensions. To traverse it and populate it with actual values, for example 1, we could use nested loops:
for (int i = 0; i < 10; ++i) { // for each row
for (int j = 0; j < 10; ++j) { // for each column
board[i][j] = 1;
}
}
What you describe for the second method only gives you a 1D array:
int *board = new int[10];
This just allocates an array with 10 elements. Perhaps you meant something like this:
int **board = new int*[4];
for (int i = 0; i < 4; i++) {
board[i] = new int[10];
}
In this case, we allocate 4 int*s and then make each of those point to a dynamically allocated array of 10 ints.
So now we're comparing that with int* board[4];. The major difference is that when you use an array like this, the number of "rows" must be known at compile-time. That's because arrays must have compile-time fixed sizes. You may also have a problem if you want to perhaps return this array of int*s, as the array will be destroyed at the end of its scope.
The method where both the rows and columns are dynamically allocated does require more complicated measures to avoid memory leaks. You must deallocate the memory like so:
for (int i = 0; i < 4; i++) {
delete[] board[i];
}
delete[] board;
I must recommend using a standard container instead. You might like to use a std::array<int, std::array<int, 10> 4> or perhaps a std::vector<std::vector<int>> which you initialise to the appropriate size.
In both cases your inner dimension may be dynamically specified (i.e. taken from a variable), but the difference is in the outer dimension.
This question is basically equivalent to the following:
Is int* x = new int[4]; "better" than int x[4]?
The answer is: "no, unless you need to choose that array dimension dynamically."
This code works well with very few requirements on external libraries and shows a basic use of int **array.
This answer shows that each array is dynamically sized, as well as how to assign a dynamically sized leaf array into the dynamically sized branch array.
This program takes arguments from STDIN in the following format:
2 2
3 1 5 4
5 1 2 8 9 3
0 1
1 3
Code for program below...
#include <iostream>
int main()
{
int **array_of_arrays;
int num_arrays, num_queries;
num_arrays = num_queries = 0;
std::cin >> num_arrays >> num_queries;
//std::cout << num_arrays << " " << num_queries;
//Process the Arrays
array_of_arrays = new int*[num_arrays];
int size_current_array = 0;
for (int i = 0; i < num_arrays; i++)
{
std::cin >> size_current_array;
int *tmp_array = new int[size_current_array];
for (int j = 0; j < size_current_array; j++)
{
int tmp = 0;
std::cin >> tmp;
tmp_array[j] = tmp;
}
array_of_arrays[i] = tmp_array;
}
//Process the Queries
int x, y;
x = y = 0;
for (int q = 0; q < num_queries; q++)
{
std::cin >> x >> y;
//std::cout << "Current x & y: " << x << ", " << y << "\n";
std::cout << array_of_arrays[x][y] << "\n";
}
return 0;
}
It's a very simple implementation of int main and relies solely on std::cin and std::cout. Barebones, but good enough to show how to work with simple multidimensional arrays.
this can be done this way
I have used Operator Overloading
Overloaded Assignment
Overloaded Copy Constructor
/*
* Soumil Nitin SHah
* Github: https://github.com/soumilshah1995
*/
#include <iostream>
using namespace std;
class Matrix{
public:
/*
* Declare the Row and Column
*
*/
int r_size;
int c_size;
int **arr;
public:
/*
* Constructor and Destructor
*/
Matrix(int r_size, int c_size):r_size{r_size},c_size{c_size}
{
arr = new int*[r_size];
// This Creates a 2-D Pointers
for (int i=0 ;i < r_size; i++)
{
arr[i] = new int[c_size];
}
// Initialize all the Vector to 0 initially
for (int row=0; row<r_size; row ++)
{
for (int column=0; column < c_size; column ++)
{
arr[row][column] = 0;
}
}
std::cout << "Constructor -- creating Array Size ::" << r_size << " " << c_size << endl;
}
~Matrix()
{
std::cout << "Destructpr -- Deleting Array Size ::" << r_size <<" " << c_size << endl;
}
Matrix(const Matrix &source):Matrix(source.r_size, source.c_size)
{
for (int row=0; row<source.r_size; row ++)
{
for (int column=0; column < source.c_size; column ++)
{
arr[row][column] = source.arr[row][column];
}
}
cout << "Copy Constructor " << endl;
}
public:
/*
* Operator Overloading
*/
friend std::ostream &operator<<(std::ostream &os, Matrix & rhs)
{
int rowCounter = 0;
int columnCOUNTER = 0;
int globalCounter = 0;
for (int row =0; row < rhs.r_size; row ++)
{
for (int column=0; column < rhs.c_size ; column++)
{
globalCounter = globalCounter + 1;
}
rowCounter = rowCounter + 1;
}
os << "Total There are " << globalCounter << " Elements" << endl;
os << "Array Elements are as follow -------" << endl;
os << "\n";
for (int row =0; row < rhs.r_size; row ++)
{
for (int column=0; column < rhs.c_size ; column++)
{
os << rhs.arr[row][column] << " ";
}
os <<"\n";
}
return os;
}
void operator()(int row, int column , int Data)
{
arr[row][column] = Data;
}
int &operator()(int row, int column)
{
return arr[row][column];
}
Matrix &operator=(Matrix &rhs)
{
cout << "Assingment Operator called " << endl;cout <<"\n";
if(this == &rhs)
{
return *this;
} else
{
delete [] arr;
arr = new int*[r_size];
// This Creates a 2-D Pointers
for (int i=0 ;i < r_size; i++)
{
arr[i] = new int[c_size];
}
// Initialize all the Vector to 0 initially
for (int row=0; row<r_size; row ++)
{
for (int column=0; column < c_size; column ++)
{
arr[row][column] = rhs.arr[row][column];
}
}
return *this;
}
}
};
int main()
{
Matrix m1(3,3); // Initialize Matrix 3x3
cout << m1;cout << "\n";
m1(0,0,1);
m1(0,1,2);
m1(0,2,3);
m1(1,0,4);
m1(1,1,5);
m1(1,2,6);
m1(2,0,7);
m1(2,1,8);
m1(2,2,9);
cout << m1;cout <<"\n"; // print Matrix
cout << "Element at Position (1,2) : " << m1(1,2) << endl;
Matrix m2(3,3);
m2 = m1;
cout << m2;cout <<"\n";
print(m2);
return 0;
}
int row, col;
cout << "Enter row size:";
cin >> row;
cout << "\ncol:";
cin >> col;
int *p_board[row];
for (int i=0; i < row; i++)
p_board[i] = new int[col];
for (int i=0; i < row; i++)
{
for (int j=0; j < col; j++)
{
p_board[i][j] = j;
cout << p_board[i][j] << " ";
}
cout << endl;
}
cout << endl << endl;
// in this method of declaring 2d array using new ..first you have created an array of pointers locally not using new so it will be created on stack not on heap then you have created an array using new on every index of p_board, these all arrays are created on heap but due to locally created p_board will make these array of no use becoz when you will use this method in any function and will try to return the p_board pointer from that function ..at that time p_board will be vanished from stack because it was created on stack ...but 2nd method is preferable to use/
int **p_p_board;
p_p_board = new int* [row];
for (int i=0; i < row; i++)
p_p_board[i] = new int[col];
for (int i=0; i < row; i++)
{
for (int j=0; j < col; j++)
{
p_p_board[i][j] = j;
cout << p_p_board[i][j] << " ";
}
cout << endl;
}
//in this method both array will be created on heap