Dynamic Multidimensional array in C++ - c++

I made Matrix Multiplication program in c++ using dynamic Multidimensional arrays.
problem is when i enter test values
matrix A = row1{ 1 } , row2 { 2 } matrix B = row1 {1 ,2 , 3} , it stops working at the loop where user
inputs values of first array , i found it using debugging. but program works fine when i enter
matrix A = row1{ 1 , 2 } , row2 { 3 , 4 } matrix B = row1 {5 , 6 } , row2 {7 , 8}
i want this program to be a general program that can multiply all matrixs
#include <iostream>
using namespace std;
class Lab_02
{
public:
void Product(){
int a1Rows, a1Columns;
int a2Rows, a2Columns;
cout << "Plz Enter the no. of rows for Array 1 :";
cin >> a1Rows;
cout << "Plz Enter the no. of columns for Array 1 :";
cin >> a1Columns;
cout << "Plz Enter the no. of rows for Array 2 :";
cin >> a2Rows;
cout << "Plz Enter the no. of columns for Array 2 :";
cin >> a2Columns;
int **dynamicArray = 0;
int **dynamicArray2 = 0;
int **dynamicArray3 = 0;
cout << endl;
for (int i = 0; i < a1Rows; i++)
{
dynamicArray3 = new int *[a1Rows];
}
for (int i = 0; i < a2Columns; i++)
{
dynamicArray3[i] = new int[a2Columns];
}
// memory allocated for elements of rows.
for (int i = 0; i < a1Rows; i++)
{
dynamicArray = new int *[a1Rows];
}
// memory allocated for elements of each column.
for (int i = 0; i < a1Columns; i++)
{
dynamicArray[i] = new int[a1Columns];
}
// memory allocated for elements of rows.
for (int i = 0; i < a2Rows; i++)
{
dynamicArray2 = new int *[a2Rows];
}
// memory allocated for elements of each column.
for (int i = 0; i < a2Columns; i++)
{
dynamicArray2[i] = new int[a2Columns];
}
cout << "enter the values or array 1 \n";
for (int i = 0; i < a1Rows; i++)
{
for (int j = 0; j < a1Columns; j++)
{
cout << "array[" << i << "][" << j << "]\t";
cin >> dynamicArray[i][j];
}
}
cout << "enter the values or array 2 :\n";
for (int i = 0; i < a2Rows; i++)
{
for (int j = 0; j < a2Columns; j++)
{
cout << "array[" << i << "][" << j << "]\t";
cin >> dynamicArray2[i][j];
}
}
int sum;
for (int i = 0; i < a1Rows; i++)
{
for (int j = 0; j < a1Columns ; j++)
{
sum = 0;
for (int k = 0; k < a2Columns ; k++)
{
sum = sum + (dynamicArray[i][k] * dynamicArray2[k][j]);
}
dynamicArray3[i][j] = sum;
}
}
cout <<"Result" << endl << endl;
for (int i = 0; i < a1Rows; i++)
{
for (int j = 0; j < a2Columns; j++)
{
cout << dynamicArray3[i][j] << "\t";
}
cout << endl;
}
}
};
void main(void)
{
Lab_02 object;
object.Product();
}

Your memory allocations for the matricies are the issue.
Change them to something like the following
// memory allocated for elements of rows.
dynamicArray = new int *[a1Rows];
// memory allocated for elements of each column.
for (int i = 0; i < a1Rows; i++)
{
dynamicArray[i] = new int[a1Columns];
}
You need to allocate one array of array for the rows and then you need to loop over the rows and allocate the columns.

The issue with the code is that you are not supposed to allocate the "rows" in a loop. All you need is one allocation for the rows, and then loop to allocate the data for each row.
So for example, instead of this:
for (int i = 0; i < a1Rows; i++)
{
dynamicArray = new int *[a1Rows];
}
// memory allocated for elements of each column.
for (int i = 0; i < a1Columns; i++)
{
dynamicArray[i] = new int[a1Columns];
}
The correct way would be this:
dynamicArray = new int *[a1Rows];
for (int i = 0; i < a1Columns; i++)
{
dynamicArray[i] = new int[a1Columns];
}
You made the same mistake for each of the loops.
Also, some points:
You failed to deallocate the memory that was allocated.
If you used std::vector, then things become much easier.
You need to check if the matrices are multiplyable before performing the sum loop. By multiplyable meaning that the number of columns and rows of matrix A and B satisfy the requirements for multiplication of A and B.
for (int i = 0; i < a1Rows; i++)
{
for (int j = 0; j < a1Columns; j++)
{
sum = 0;
for (int k = 0; k < a2Columns; k++)
sum = sum + (dynamicArray[i][k] * dynamicArray2[k][j]);
dynamicArray3[i][j] = sum;
}
}
This loop will go haywire if the dynamicArray1 and dynamicArray2 do not have the requisite number of columns and rows before multiplying.
First, the following test should be done before multiplying:
if (a1Columns != a2Rows)
return;
Second, your k loop is wrong. It should be this:
for (int k = 0; k < a2Rows; k++)
sum = sum + (dynamicArray[i][k] * dynamicArray2[k][j]);
dynamicArray3[i][j] = sum;

Related

C++ Program with matrix class ending abruptly

I am writing a matrix class where I need to perform some matrix calculations in the main program. I am not sure why the program is ending abruptly when user chooses a matrix of size more than 2x2 matrix. The std::cin works fine until two rows but program ends after the loop reaches third row. Only part of the code is shown below which is related to my question.
#include<iostream>
#include <vector>
#include <cassert>
using std::vector;
using namespace std;
class Matrix {
private:
int rows;
int cols;
int **vtr;
public:
Matrix(int m = 2, int n = 2)
{
rows = m;
cols = n;
vtr = new int*[m];
for (int i = 0; i < m; i++)
{
vtr[i] = new int [n];
}
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
vtr[i][j] = 0;
}
}
}
void read()
{
cout << "Enter the number of rows and columns of Matrix separated by a space: ";
cin >> rows >> cols;
Matrix a(rows, cols);
a.write();
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
cout << "(" << i << "," << j << ") : ";
cin >>vtr[i][j];
}
}
}
void write()
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
cout << vtr[i][j] << " ";
}
cout << endl;
}
cout << endl << endl;
}
};
int main()
{
Matrix A, B, C;
int row, column ;
cout << "For Matrix A" << endl;
A.read();
cout << "For Matrix B " << endl;
B.read();
cout << "For Matrix C" << endl;
C.read();
}
Since the 2D array, vtr is created when declaring the Matrix object, you can move the vtr creation after reading the console input like below.
Matrix(int m = 2, int n = 2)
{
/*rows = m;
cols = n;
vtr = new int*[m];
for (int i = 0; i < m; i++)
{
vtr[i] = new int [n];
}
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
vtr[i][j] = 0;
}
}*/
}
void read()
{
cout << "Enter the number of rows and columns of Matrix separated by a space: ";
cin >> rows >> cols;
vtr = new int*[rows];
for (int i = 0; i < rows; i++)
{
vtr[i] = new int [cols];
}
//Matrix a(rows, cols);
//write();
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
cout << "(" << i << "," << j << ") : ";
cin >>vtr[i][j];
}
}
write(); //Prints the array
}
The three matrixs will be construct when you define Matrix A, B, C. So the matrix size is 2x2. When you call function cin to assign value to some position is not in 2x2 will not work.

C++ How to delete a specific row or column in a dynamically allocated 2d array? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
So, I dynamically allocated a 2d array in this way:
int rs, co;
cin >> ro;
cin >> co;
int **array = new int* [ro];
for(int i = 0; i < ro; i++){
array[i] = new int [co];
}
I filled it:
for(int i = 0; i < ro; i++){
for(int j = 0; j < co; j++){
cout << "Row: " << i << " Column: " << j << " : ";
cin >> *(*(array + i) + j);
}
}
My question is:
how can I deallocate an X row or column where X is given by the user?
I know I should use "delete" command but I can not understand how
You cannot delete a column, but you can delete a row.
If this doesn't make sense to you directly, try reading my 2D dynamic array (C). Focus on the figure:
I know that my link is in C, but what you try to do reminds me of C. In C++, you could use an std::vector<int> instead.
I assume that you know that you can write:
array[i][j]
instead of:
*(*(array + i) + j)
Example on deleting first row on a matrix with two rows.
delete [] array[0];
int **tmp = new int*[1];
tmp[0] = array[1];
delete [] array;
array = tmp;
Generalized example:
#include <iostream>
using namespace std;
int main(void) {
int ro = 3, co = 2;
int **array = new int* [ro];
for(int i = 0; i < ro; i++){
array[i] = new int [co];
}
// fill and print the matrix
for(int i = 0; i < ro; i++){
for(int j = 0; j < co; j++) {
array[i][j] = i;
cout << array[i][j] << " ";
}
cout << endl;
}
int rowToDel = 1;
delete [] array[rowToDel];
int **tmp = new int*[ro - 1];
int tmpI = 0;
for(int i = 0; i < ro; ++i)
if(i != rowToDel)
tmp[tmpI++] = array[i];
delete [] array;
array = tmp;
ro = ro - 1;
cout << "Array after deleting " << rowToDel << "-th row\n";
for(int i = 0; i < ro; i++){
for(int j = 0; j < co; j++) {
cout << array[i][j] << " ";
}
cout << endl;
}
return 0;
}
Output:
0 0
1 1
2 2
Array after deleting 1-th row
0 0
2 2
You can delete a row by simply calling
delete [] array[i];
You cannot delete columns, since columns are not lined up like rows are.
For example, lets say we have a 2D array like this:
row1: abcd
row2: efgh
row3: ijkl
In the computer, the data is actually lined up like this:
abcd .... other data.... efgh .... other data..... ijkl
Deleting a row is easy, since the computer has them lined up next to eachother. But, because the rows are created dynamically, they do NOT have to reside next to eachother. They are allocated wherever there is space is available.
So, the columns are not lined up at all, and it doesn't make sense to "deallocate".
With a 2D array of vector is easy.
Just use erase function for rows.
For columns, iterate on rows and delete each element:
int ro = 4, co = 3;
vector< vector<int> > vec(ro);
for (int i = 0; i < ro; i++)
vec[i].resize(co);
// fill and print the matrix
for (int i = 0; i < vec.size(); i++) {
for (int j = 0; j < vec[i].size(); j++) {
vec[i][j] = i;
cout <<vec[i][j] << " ";
}
cout << endl;
}
int rowErasePosition = 1;
vec.erase(vec.begin() + rowErasePosition);
// reprinting
cout << "second row deleted" << endl;
for (int i = 0; i < vec.size(); i++) {
for (int j = 0; j < vec[i].size(); j++) {
cout << vec[i][j] << " ";
}
cout << endl;
}
//deleting column
int columnErasePosition = 1;
for (int i = 0; i < vec.size(); i++) {
vec[i].erase(vec[i].begin() + columnErasePosition);
}
// reprinting
cout << "second column deleted" << endl;
for (int i = 0; i < vec.size(); i++) {
for (int j = 0; j < vec[i].size(); j++) {
cout << vec[i][j] << " ";
}
cout << endl;
}

How do I set all the diagonals in a matrix equal to zero?

I have a problem with my homework that asks me to have the compiler print out a matrix in which all the diagonals are outputted as zero. I also have to pass it to a function. However, I have no idea how to do this..
Here is my code:
#include <iostream>
using namespace std;
int diagonals();
int main()
{
//problem 1
int matrix[3][3];
for (int i = 1; i <= 3; i++)
{
for (int j = 1; j <= 3 ; j++)
{
cout << "Row " << i << " column " << j<< ": ";
cin >> matrix[i][j];
}
}
for (int i = 1; i <= 3; i++)
{
for (int j = 1; j <= 3; j++)
{
cout << matrix[i][j] << " ";
}
cout << endl;
}
cout << "\nReverse of the matrix:" << endl;
for (int j = 1; j <= 3; j++)
{
for (int i = 1; i <= 3; i++)
{
cout << matrix[i][j] << " ";
}
cout << endl;
}//end of problem 1
//problem 2
cout << "Diagonals changed to 0:\n" << endl;
}
your matrix declaration says int matrix[3][3]; that it has three 1-D array & in each 1-D array you can store three elements. And in C/C++ array index starts from zero.
Problematic statement is for (int i = 1; i <= 3; i++) as you are skipping matrix[0][0] and trying to store into matrix[3][3] which doesn't exist which in turn causes undefined behavior.
So firstly start iterating loop from 0 to number of rows & column respectively.
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3 ; j++) {
cout << "Row " << i << " column " << j<< ": ";
cin >> matrix[i][j];
}
}
Coming to task you mentioned, print out a matrix in which all the diagonals are outputted as zero. ? write one condition so that if row value & col value are equal then assign it to zero otherwise scan from user. Here is the sample code
int main(void) {
int matrix[3][3] = { 0 }; /* initialize it */
int row = sizeof(matrix)/sizeof(matrix[0]); /* find no of rows */
int col = sizeof(matrix[0])/sizeof(matrix[0][0]);/* find no of columns */
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if( i == j)
matrix[i][j] = 0;/* when i and j are equal means thats diagonal and assign it to zero */
else /* if its not diagonal then scan from user */
std::cin>>matrix[i][j];
}
}
return 0;
}
Secondly, I also have to pass it to a function. for this learn how to pass 2d array to a function. Here is the sample example.
void diagonal(int (*mat)[3],int row, int col) { /* mat is pointer to an array */
std::cout<<"printing matrix "<<std::endl;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
std::cout<<mat[i][j]<<"\t";
}
std::cout<<std::endl;
}
}
And call diagonal() like below from main() function as
diagonal(matrix,row,col); /* pass matrix, no of rows, no of columns */

Dynamically Allocated 2D Array EXC_BAD_ACCESS Error in C++

I'm in the early stages of my program and right now I'm simply trying to initialize a 2D array to hold all dashes but I keep getting a ECX_BAD_ACCESS error. My code seems to work with a square array (ex: 5x5 or 6x6) but if I do 10 by 5 I get the error.
void readMatrix(char **twoDarray, int &rows, int &cols)
{
std::cout << "Enter number of rows for board";
std::cin >> rows;
std::cout << "Enter number of columns for board";
std::cin >> cols;
//dynamic 2D array initialization
twoDarray = new char*[rows];
for(int i = 0; i < cols; ++i)
twoDarray[i] = new char[rows];
//set elements of array to dashes
for(int i = 0; i < rows; ++i)
for(int j = 0; j < cols; ++j){
twoDarray[i][j] = '-';
}
//printing the array
for(int i = 0; i < rows; ++i){
std::cout << " " << std::endl;
for(int j = 0; j < cols; ++j)
std::cout << twoDarray[i][j] << " ";
}
}
Your first for-loop should go from 0 to #rows, not #cols. Also, in the body of that same loop allocate cols, not rows.

Sort 2D Array Row's Depend on the last column

I want to Write a Program in c++ that swap the row but my code only sort the element of the array.
For example:
I made a array of 3*5.
I input data as follows
1 2 3 4 10
5 6 7 8 26
9 1 2 3 15
Now I want to swap the rows by ascending order depends on the last column.i.e.
5 6 7 8 26
9 1 2 3 15
1 2 3 4 10
My code Only Sort the Row form left to Right.
int arr[3][5], sum, temp;
for(int i =0; i<3; i++)
{
sum=0;
for(int j =0; j<4; j++)
{
cout << "Enter "<<j+1<<" Number of "<<i+1<<" Student";
cin >> arr[i][j];
sum = sum + arr[i][j];
}
arr[i][4]=sum;
}
for(int i = 0; i<3; i++)
{
for(int j = 0; j<5; j++)
{
cout << arr[i][j]<<"\t";
}
cout << endl;
}
cout<<"----------------"<<endl;
for(int i=0;i<3;i++)
{
for(int j = 0;j<4;j++)
{
for(int k =0;k<4;k++)
{
if(arr[i][j]<arr[i][k])
{
temp=arr[i][j];
arr[i][j]=arr[i][k];
arr[i][k]=temp;
}
}
}
}
for(int i =0;i<3;i++)
{
for(int j =0;j<5;j++)
{
cout<<arr[i][j]<<"\t";
}
cout<<endl;
}
If performance is not of significant concern, just use the same idea as Bubble sort.
Compare last column element between each pair of rows, and if not in order swap the rows. This can be done with a loop and a temporary variable.
if(matrix[i][cols-1] > matrix[j][cols-1])
{
int temp ;
for(int k = 0; k < cols; ++k)
{
temp = matrix[i][k] ;
matrix[i][k] = matrix[j][k] ;
matrix[j][k] = temp ;
}
}
Since you are using C++, you can use std::array if your matrix has fixed size rows and columns. i.e.
std::array<std::array<int, colums>, rows> matrix ;
Here is a working example which uses std::swap to do the swapping of rows. The sorting routine is essentially the bubble sort.
for(int i = 0; i < rows; ++i)
for(int j = 0; j < i; ++j)
if(matrix[j][cols-1] > matrix[i][cols-1])
std::swap(matrix[i], matrix[j]);
Maybe this is your answer:
int arr[3][5], sum, temp;
for (int i = 0; i<3; i++)
{
sum = 0;
for (int j = 0; j<4; j++)
{
cout << "Enter " << j + 1 << " Number of " << i + 1 << " Student";
cin >> arr[i][j];
sum = sum + arr[i][j];
}
arr[i][4] = sum;
}
cout << endl << endl;
for (int i = 0; i<3; i++)
{
for (int j = 0; j<5; j++)
{
cout << arr[i][j] << "\t";
}
cout << endl;
}
cout << "----------------" << endl << endl;
int tmp[5],i,j,k;
for ( i = 0; i<3; i++)
{
for ( j = 0; j<3; j++)
{
if (arr[j][4]<arr[i][4])
{
for ( k = 0; k <= 4; k++){
int t = arr[i][k];
arr[i][k] = arr[j][k];
arr[j][k] = t;
}
}
}
}
for (int i = 0; i<3; i++)
{
for (int j = 0; j<5; j++)
{
cout << arr[i][j] << "\t";
}
cout << endl;
}