Error happens during deleting the dynamic allocated 2d array? - c++

I am learning c++ and made my code of Matrix generating Class with operations.
However, When I try to delete the two matrices which input by user after the whole works, it pops up the message:
"Exception thrown at 0x0F4DBF9B (ucrtbased.dll) in Matrix 1.3.exe: 0xC0000005: Access violation reading location 0xDDDDDDCD"
at "(45)the delete[] arr[i];" line, which is in the destructor.
I tried to remove the brackets, but as I need those brackets to remove arrays, it also did not work.
Do you have any idea whats going wrong here?
#include <iostream>
#include <iomanip>
using namespace std;
class Matrix
{
private:
int row, col;
int** arr;
public:
Matrix(int, int);
~Matrix();
int getRow() const;
int getCol() const;
int** getMatrixArr() const;
friend Matrix* operator+(const Matrix&, const Matrix&);
friend Matrix* operator-(const Matrix&, const Matrix&);
friend Matrix* operator*(const Matrix&, const Matrix&);
friend Matrix* operator*(const Matrix&, int);
friend ostream& operator<<(ostream&, const Matrix*);
friend istream& operator>>(istream&, const Matrix&);
};
//construct and destruct--------------------------------------------------------------------------------------------------
Matrix::Matrix(int row, int col)
{
this->row = row;
this->col = col;
arr = new int*[row];
for (int i = 0; i < row; i++)
{
arr[i] = new int[col];
}
}
Matrix::~Matrix()
{
for (int i = 0; i < row; i++)
{
delete[] arr[i];
}
delete[] arr;
}
//getters------------------------------------------------------------------------------------------------------------------
int Matrix::getRow() const
{
return row;
}
int Matrix::getCol() const
{
return col;
}
int** Matrix::getMatrixArr() const
{
return arr;
}
//operation methods(OpOv)----------------------------------------------------------------------------------------------------------
Matrix* operator+(const Matrix& m, const Matrix& n)
{
Matrix* sum = new Matrix(m.row, m.col);
cout << "calculating..." << endl;
for (int i = 0; i <m.row; i++)
{
for (int j = 0; j <m.col; j++)
{
cout << setw(3) << m.arr[i][j] << "+" << n.arr[i][j];
sum->arr[i][j] = m.arr[i][j] + n.arr[i][j];
}
cout << endl;
}
return sum;
}
Matrix* operator-(const Matrix& m, const Matrix& n)
{
Matrix* sum = new Matrix(m.row, m.col);
cout << "caluclating..." << endl;
for (int i = 0; i < m.row; i++)
{
for (int j = 0; j < m.col; j++)
{
cout << setw(3) << m.arr[i][j] << "-" << n.arr[i][j];
sum->arr[i][j] = m.arr[i][j] - n.arr[i][j];
}
cout << endl;
}
return sum;
}
Matrix* operator*(const Matrix& m, const Matrix& n)
{
Matrix* sum = new Matrix(m.row, n.col);
cout << "calculating..." << endl;
for (int i = 0; i < m.row; i++)
{
for (int j = 0; j < n.col; j++)
{
sum->arr[i][j] = 0;
}
}
for (int i = 0; i < m.row; i++)
{
for (int j = 0; j < n.col; j++)
{
for (int t = 0; t < m.col; t++)
{
cout << setw(3) << "+" << m.arr[i][t] << "x" << n.arr[t][j];
sum->arr[i][j] += m.arr[i][t] * n.arr[t][j];
}
}
cout << endl;
}
return sum;
}
Matrix* operator*(const Matrix& m, int num)
{
Matrix* sum = new Matrix(m.row, m.col);
cout << "calculating..." << endl;
for (int i = 0; i < m.row; i++)
{
for (int j = 0; j < m.col; j++)
{
cout << setw(3) << m.arr[i][j] << "x" << num;
sum->arr[i][j] = m.arr[i][j] * num;
}
cout << endl;
}
return sum;
}
// input & output ---------------------------------------------------------------------------------------------------------------------
istream& operator>>(istream& is, const Matrix& m)
{
cout << "Enter the values for the Matrix (expecting: " << m.row * m.col << "): ";
for (int i = 0; i < m.row; i++)
{
for (int j = 0; j < m.col; j++)
{
is >> m.arr[i][j];
}
}
return is;
}
ostream& operator<<(ostream& os, const Matrix* m)
{
cout << "result: " << endl;
for (int i = 0; i < m->row; i++)
{
for (int j = 0; j < m->col; j++)
{
os << setw(3) << m->arr[i][j];
}
cout << endl;
}
return os;
}
//main-------------------------------------------------------------------------------------------------------------------------------------
int main()
{
int rowNum1, colNum1;
cout << "what is the row of the Matrix 1?: " << endl;
cin >> rowNum1;
cout << "What is the column for the Matrix 1?: " << endl;
cin >> colNum1;
Matrix m1(rowNum1, colNum1);
cin >> m1;
int rowNum2, colNum2;
cout << "what is the row of the Matrix 2?: " << endl;
cin >> rowNum2;
cout << "What is the column for the Matrix 2?: " << endl;
cin >> colNum2;
Matrix m2(rowNum2, colNum2);
cin >> m2;
int choice;
do
{
cout << "Now, what operation do you want to use?" << endl;
cout << "1) addition, 2) Sub action, 3)Multiplication, 4) scalar multiplication 5) quit" << endl << ":";
cin >> choice;
if (choice == 1)
{
if (m1.getRow() != m2.getRow() || m1.getCol() != m2.getCol())
{
cout << "The number of rows or columns of both Matrices are not same, you cannot add them together." << endl;
return 0;
}
else
{
Matrix * result = (m1 + m2);
cout << result << endl;
}
}
else if (choice == 2)
{
if (m1.getRow() != m2.getRow() || m1.getCol() != m2.getCol())
{
cout << "The number of rows or columns of both Matrices are not same, you cannot add them together." << endl;
return 0;
}
else
{
Matrix * result = (m1 - m2);
cout << result << endl;
}
}
else if (choice == 3)
{
if (m1.getCol() != m2.getRow())
{
cout << "Your first Matrix's number of columns and the second Matrice's number of rows are not accorded." << endl;
return 0;
}
else
{
Matrix* result = (m1 * m2);
cout << result << endl;
}
}
else if (choice == 4)
{
int value;
cout << "What is the integer value for the multiplication?: ";
cin >> value;
int MatCho;
cout << "First Matrix or Second Matrix(1 or 2)?: ";
cin >> MatCho;
if (MatCho == 1)
{
Matrix* result = (m1 * value);
cout << result << endl;
}
else if (MatCho == 2)
{
Matrix* result = (m2 * value);
cout << result << endl;
}
else
{
cout << "invalid input" << endl;
}
}
else if (choice == 5)
{
break;
}
else
{
cout << "Invalid input" << endl;
}
} while (choice != 5);
m1.~Matrix();
m2.~Matrix();
return 0;
}

Two issues here:
Never call destructor explicitly like you do with m1 and m2 here. Their destructors will be called automatically at the end of the main function in any case. So for you the destructors will run twice. On the second run, the array of pointers has already been deleted. But row, col and the pointer still has their old values and will try to access and delete already freed memory.
All your operations you do on the matrices will leak memory. You are using new inside the operator functions but never deleting the result. It is a bad habit expecting the user of a function to delete memory you have allocated. Return by value instead. This will actually not infer any performance loss, if you implement a move constructor (http://www.learncpp.com/cpp-tutorial/15-3-move-constructors-and-move-assignment/)

Remove the manual call to the destructors. As they're stack-allocated, the C++ compiler you use will handle them when you exit the main function, even if you already called them (which is what is happening).

Related

Define class matrix of integers using vector

I have run the following code.
Errors I got are: invalid types array subscripts
Is there any mistake in using the constructor?
While I run it normally without using any constructor, I got an error output.
These are the errors I got, please check out what my mistake is:
invalid types 'const int[int]' for array subscript inside the = operator
and
[Error] invalid types 'int[int]' for array subscript inside print function in the program.
#include<iostream>
#include<vector>
using namespace std;
class Matrix
{
int i,j,x,y;
vector<int> v;
vector<int> b;
public:
Matrix()
{
}
Matrix(int m, int n) //Main constructor
{
x=m;
y=n;
vector< vector <int> > v(x,vector <int>(y));
cout<< "enter values into the vector" << endl;
for(int i = 0; i < x; ++i)
{
for (int j = 0; j < y; ++j)
{
cin >> v[i][j];
}
}
}
Matrix(const Matrix &t)
{
x=t.x;
y=t.y;
v=t.v;
cout << "copy constructor called" << endl;
}
~matrix()
{
cout << "destructor called" << endl;
}
Matrix operator=( const Matrix &r)
{
x=r.x;
y=r.y;
vector< vector <int> > b(x,vector <int>(y));
for (i=0;i<x;++i)
{
for (j=0;j<y;++j)
{
b[i][j]=r.v[i][j];
}
}
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
{
cout << b[i][j] << " ";
}
cout << endl;
}
}
void print()
{
for (i = 0; i < x; i++)
{
for (j = 0; j < y; j++)
{
cout << v[i][j] << " ";
}
cout << endl;
}
}
};
int main()
{
int d1,d2;
cout << "enter row,column values" << endl;
cin >> d1 >> d2;
Matrix ob1();
Matrix ob2(d1,d2);
cout << "elements in the matrix using constructor are" << endl;
ob2.print();
Matrix ob3(ob2);
cout << "elements in the copy constructor" << endl;
ob3.print();
cout << "after overloading assignment operator" << endl;
Matrix ob4;
ob4=ob2;
return 0;
}
Thank you in advance. It looks there is too much code with respect to text in this question, so needed to add a few words here.
As #Federico quickly spotted, class data v is initially defined just as a vector<int>, but then used throughout the member functions as vector< vector<int> >.
No need to define b and loop indices i,j as class data.
In addition, v in the assignment operator was redefined locally, so even after having correctly compiled, the program would not have yielded the desired results.
This MWE below should work as intended
#include<iostream>
#include<vector>
using namespace std;
class Matrix
{
int x,y; // redundant class data erased
vector< vector <int> > v;
public:
Matrix(): x(0), y(0), v(0)
{
}
Matrix(int m, int n) // Main constructor
{
x=m;
y=n;
v = vector< vector<int> >(x,vector <int>(y, 0)); // in original version, this class data was redefined locally
cout<< "enter values into the vector" << endl;
for(int i = 0; i < x; ++i)
{
for (int j = 0; j < y; ++j)
{
cin >> v[i][j];
}
}
}
Matrix(const Matrix &t)
{
x=t.x;
y=t.y;
v=t.v;
cout << "copy constructor called" << endl;
}
~Matrix()
{
cout << "destructor called" << endl;
}
Matrix& operator=(const Matrix &r) // needs to output a reference
{
if (this == &r) // check self-assignment
return *this;
x = r.x;
y = r.y;
vector< vector<int> > b(x,vector <int>(y, 0));
for (int i = 0; i < x; ++i)
{
for (int j = 0; j < y; ++j)
{
b[i][j] = r.v[i][j];
}
}
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
{
cout << b[i][j] << " ";
}
cout << endl;
}
return *this;
}
void print()
{
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
{
cout << v[i][j] << " ";
}
cout << endl;
}
}
};
int main()
{
int d1,d2;
cout << "enter row, column values" << endl;
cin >> d1 >> d2;
Matrix ob1();
Matrix ob2(d1,d2);
cout << "elements in the matrix using constructor are" << endl;
ob2.print();
Matrix ob3(ob2);
cout << "elements in the copy constructor" << endl;
ob3.print();
cout << "after overloading assignment operator" << endl;
Matrix ob4;
ob4=ob2;
return 0;
}
Output:
enter row, column values
3 3
enter values into the vector
1 2 3 4 5 6 7 8 9
elements in the matrix using constructor are
1 2 3
4 5 6
7 8 9
copy constructor called
elements in the copy constructor
1 2 3
4 5 6
7 8 9
after overloading assignment operator
1 2 3
4 5 6
7 8 9
destructor called
destructor called
destructor called

I am trying to perform the tranpose function but can not get it

I have problems with the final void function i tried to assingn it to a variable i declared int l but i cant since the functions return type is void and for some reason i do get the same result for both the row and column sum and toal sum and i am confused about what should i do or how to calculate row or column seperately here is the question
Write a menu driven C++ program to do following operation on two dimensional array A of size m x n. You should use user-defined functions which accept 2-D array A, and its size m and n as arguments. The options are:
To input elements into matrix of size m x n
To display elements of matrix of size m x n
Sum of all elements of matrix of size m x n
To display row-wise sum of matrix of size m x n
To display column-wise sum of matrix of size m x n
To create transpose of matrix B of size n x n
#include<iostream>
using namespace std;
void showcases();
void input_element(int A[][20], int& m, int& n);
void display_matrix(int A[][20], int& m, int& n);
int sum(int A[][20], int& m, int& n);
int row_sum(int A[][20], int& m, int& n);
int col_sum(int A[][20], int& m, int& n);
void transp(int A[][20], int B[][20], int& m, int& n);
int main()
{
int a = 0, b = 0, choice = 0, A[10][20], B[10][20], n = 0, x = 0, y = 0, z = 0, l = 0;
for (int k = 0; choice <= 6; k++)
{
showcases();
x = sum(A, a, b);
y = row_sum(A, a, b);
z = col_sum(A, a, b);
cin >> choice;
if (choice == 1) {
input_element(A, a, b);
}
if (choice == 2) {
display_matrix(A, a, b);
}
if (choice == 3) {
cout << "The sum of the matrix elements is " << x << endl;
}
if (choice == 4) {
cout << "The sum of the matrix rows is " << y << endl;
}
if (choice == 5) {
cout << "The sum of the matrix columns is " << z << endl;
}
if (choice == 6) {
transp(A, B, a, b);
cout << endl;
}
if (choice >= 7 || choice <= 0) {
cout << "Your choice is invalid" << endl;
}
}
system("pause");
return 0;
}
void input_element(int A[][20], int& m, int& n)
{
int row, col;
cout << "Enter the number of rows: ";
cin >> m;
cout << "Enter the number of columns: ";
cin >> n;
for (int r = 0; r < m; r++)
for (int colum = 0; colum < n; colum++)
{
cout << "Enter the elements for the array: ";
cin >> A[r][colum];
}
}
void display_matrix(int A[][20], int& m, int& n)
{
for (int r = 0; r < m; r++)
for (int colum = 0; colum < n; colum++)
{
cout << "Entered element is " << ": ";
cout << A[r][colum];
cout << endl;
}
}
int sum(int A[][20], int& m, int& n)
{
int s = 0, r, colum;
for (r = 0; r < m; r++)
{
for (colum = 0; colum < n; colum++)
{
s += A[r][colum];
}
}
return s;
}
int row_sum(int A[][20], int& m, int& n)
{
int r_s = 0, r, colum;
for (r = 0; r < m; r++)
{
for (colum = 0; colum < n; colum++)
{
r_s += A[r][colum];
}
}
return r_s;
}
int col_sum(int A[][20], int& m, int& n)
{
int col_s(0), colum, r;
for (r = 0; r < m; r++)
{
for (colum = 0; colum < n; colum++)
{
col_s += A[colum][r];
}
}
return col_s;
}
void transp(int A[][20], int B[][20], int& m, int& n)
{
int r, colum;
for (r = 0; r < m; r++)
{
for (colum = 0; colum < n; colum++)
B[r][colum] = A[colum][r];
}
for (r = 0; r < m; r++)
{
for (colum = 0; colum < n; colum++)
cout << B[r][colum];
}
return;
}
void showcases()
{
cout << "Menu" << endl;
cout << "1. input elements" << endl;
cout << "2. Display matrix" << endl;
cout << "3. Sum of matrix elements" << endl;
cout << "4. Sum of matrix rows" << endl;
cout << "5. Sum of matrix elements" << endl;
cout << "6. The transpose of elements" << endl;
cout << "7. Exit" << endl;
cout << "Choose among the options above: ";
}
I need the row and column sum to be different and im trying to fix the transpose part
Here is the code
#include<iostream>
using namespace std;
// protype
void showcases();
void accept(int Array[][20], int& a, int& b);
void outputs(int Array[][20], int& a, int& b);
int sum(int Array[][20], int& a, int& b);
void row_sum(int Array[][20], int& a, int& b);
void col_sum(int Array[][20], int& a, int& b);
void transposed(int Array[][20], int& a, int& b);
int main()
{
// variable declaration
int a = 0, b = 0, choice = 0, A[10][20], n = 0, x = 0, y = 0, z = 0;
// For loop execution
for (int k = 0; choice <= 6; k++)
{
x = sum(A, a, b);
showcases();
cin >> choice;
cout << "----------------------------------------------" << endl;
cout << "----------------------------------------------" << endl;
if (choice == 1) {
accept(A, a, b);
cout << "-----------------------------------------------------------" << endl << endl;
}
if (choice == 2) {
outputs(A, a, b);
cout << "-----------------------------------------------------------" << endl << endl;
}
if (choice == 3) {
cout << "The sum of the matrix elements is " << x << endl;
cout << "-----------------------------------------------------------" << endl << endl;
}
if (choice == 4) {
col_sum(A, a, b);
cout << "-----------------------------------------------------------" << endl << endl;
}
if (choice == 5) {
row_sum(A, a, b);
cout << "-----------------------------------------------------------" << endl << endl;
}
if (choice == 6) {
cout << "Elements of matrix after transpose are: " << endl;
transposed(A, a, b);
cout << endl;
cout << "-----------------------------------------------------------" << endl << endl;
}
if (choice >= 7 || choice <= 0) {
cout << "Your choice is invalid" << endl;
cout << "-----------------------------------------------------------" << endl << endl;
return -1;
}
}
system("pause");
return 0;
}
// To input the elements
void accept(int Array[][20], int& a, int& b)
{
cout << "Enter number of rows for matrix: ";
cin >> a;
cout << "Enter number of columns for matrix: ";
cin >> b;
for (int i = 0; i < a; i++)
{
for (int j = 0; j < b; j++)
{
// to keep a track of your position in array
cout << "Enter elements of matrix " << "[" << i << "]" << " [" << j << "]: ";
cin >> Array[i][j];
}
}
}
// TO output the elements
void outputs(int Array[][20], int& a, int& b)
{
for (int i = 0; i < a; i++)
{
for (int j = 0; j < b; j++)
{
cout << Array[i][j] << " ";
}
cout << endl;
}
}
// To find the total sum
int sum(int Array[][20], int& a, int& b)
{
int s = 0, i, j;
for (i = 0; i < a; i++)
{
for (j = 0; j < b; j++)
{
s += Array[i][j];
}
}
return s;
}
// To find the row sum
//you only need to find the row sum
void row_sum(int Array[][20], int& a, int& b)
{
int row_s = 0;
for (int i = 0; i < a; i++)
{
for (int j = 0; j < b; j++)
{
row_s += Array[i][j];
}
cout << "sum of" << i + 1 << " Row is " << row_s;
row_s = 0;
cout << endl;
}
return;
}
// To find the column sum
//Same you were suming up all the elements
void col_sum(int Array[][20], int& a, int& b)
{
int col_s = 0;
for (int i = 0; i < a; i++)
{
for (int j = 0; j < b; j++)
{
col_s += Array[j][i];
}
cout << "sum of" << i + 1 << " column is " << col_s;
col_s = 0;
cout << endl;
}
return;
}
// To transpose (To change the elements of rows and columns) the matrix
// you do not need to call b to store A
void transposed(int Array[][20], int& a, int& b)
{
for (int i = 0; i < a; i++)
{
for (int j = 0; j < b; j++)
{
cout << Array[j][i] << " ";
}
cout << endl;
}
return;
}
// To display (To showcase) the available choiced
void showcases()
{
cout << "Menu" << endl;
cout << "1. input elements" << endl;
cout << "2. Display matrix" << endl;
cout << "3. Sum of matrix elements" << endl;
cout << "4. Sum of matrix rows" << endl;
cout << "5. Sum of matrix elements" << endl;
cout << "6. The transpose of elements" << endl;
cout << "7. Exit" << endl;
cout << "Choose among the options above: ";
}

c++ - undeclared identifier (operator ostream) with inheritance [duplicate]

This question already has answers here:
Resolve build errors due to circular dependency amongst classes
(12 answers)
Closed 5 years ago.
I can not figure out why there is an error because everything looks fine to me, I've loaded all the code, but the error is in the print operator only function. When I run the program he takes me to this function.
I have an error, but I can not understand why.
Would appreciate help.
When I run the program the error is here(in CatsPen.h):
Error 1 error C2065: 'os' : undeclared identifier
c:\users\name\documents\visual studio 2013\projects\exe8\CatsPen.h 33 1
EXE8
friend ostream& operator<<(ostream&, const CatsPen& other){
for (int i = 0; i < other.countStreet; i++){
os << other.street[i] << endl;
}
for (int i = 0; i < other.countSiami; i++){
os << other.siami[i] << endl;
}
return os;
}
main:
#include <iostream>
#include "CatsPen.h"
using namespace std;
int main(){
CatsPen pen1;
int choice = -1;
while (choice == -1){
cin >> choice;
cout << "Enter your choice: " << endl;
cout << "1-add street cat " << endl;
cout << "2-add siami cat " << endl;
cout << "3-print cats " << endl;
cout << "4-print how many cats " << endl;
cout << "5-exit" << endl;
if (choice == 1){
pen1.addStreet();
}
}
system("pause");
return 0;
}
CatsPen.h:
include "Cat.h"
#include <iostream>
using namespace std;
#ifndef CatsPen_H
#define CatsPen_H
class CatsPen{
private:
StreetCat * street;
SiamiCat * siami;
int countStreet;
int countSiami;
int numOfCats;
int emptyCage;
public:
CatsPen();
~CatsPen();
int getCountCat(){
return countStreet + countSiami;
}
bool Place();
bool addStreet();
bool addSiami();
friend ostream& operator<<(ostream&, const CatsPen& other){
for (int i = 0; i < other.countStreet; i++){
os << other.street[i] << endl;
}
for (int i = 0; i < other.countSiami; i++){
os << other.siami[i] << endl;
}
return os;
}
};
#endif;
CatsPen.cpp:
catsPen.h"
CatsPen::CatsPen(){
this->street = NULL;
this->siami = NULL;
this->numOfCats = 0;
this->countStreet = 0;
this->countSiami = 0;
this->emptyCage = 5;
}
CatsPen::~CatsPen(){
for (int i = 0; i < countStreet; i++)
delete &street[i];
delete[] street;
for (int i = 0; i < countStreet; i++)
delete &street[i];
delete[]siami;
}
bool CatsPen::Place(){
if (emptyCage > 0){
return true;
}
cout << "no have place in the pen" << endl;
return false;
}
bool CatsPen::addStreet(){
if (Place() == true){
if (countStreet == 0){
this->street = new StreetCat[1];
cin >> this->street[countStreet];
cout << this->street[countStreet];
}
else if (countStreet > 0){
StreetCat* copyArray = new StreetCat[this->countStreet + 1];
for (int i = 0; i < countStreet; i++){
copyArray[i] = street[i];
cin >> copyArray[countStreet];
delete[] street;
cout << copyArray[countStreet];
street = copyArray;
}
countStreet++;
emptyCage--;
}
cout << "no have place in the pen" << endl;
return false;
}
}
bool CatsPen::addSiami() {//add siami cat to the pen
if (Place() == true) {
if (countSiami == 0) {
this->siami = new SiamiCat[1];
cin >> this->siami[countSiami];
cout << siami[countSiami];
}
else if (countSiami > 0) {
SiamiCat*copyArray = new SiamiCat[this->countSiami + 1];
for (int i = 0; i < countSiami; i++)
copyArray[i] = siami[i];
cin >> copyArray[countSiami];
cout << copyArray[countSiami];
delete[]siami;
siami = copyArray;
}
countSiami++;
emptyCage--;
return true;
}
cout << "no have place in the pen" << endl;
return false;
}
thank's...
There is a typo in this definition
friend ostream& operator<<(ostream&, const CatsPen& other){
^^^
for (int i = 0; i < other.countStreet; i++){
os << other.street[i] << endl;
}
for (int i = 0; i < other.countSiami; i++){
os << other.siami[i] << endl;
}
return os;
}
The parameter name os is missed.
friend ostream& operator<<(ostream &os, const CatsPen& other){
^^^

Passing 2D array to a Function in c++

I am Having Problem with Passing a 2D array to a c++ Function. The function is supposed to print the value of 2D array. But getting errors.
In function void showAttributeUsage(int)
Invalid types for int(int) for array subscript.
I know the problem is with the syntax in which I am passing the particular array to function but I don't know how to have this particular problem solved.
Code:
#include <iostream>
using namespace std;
void showAttributeUsage(int);
int main()
{
int qN, aN;
cout << "Enter Number of Queries : ";
cin >> qN;
cout << "\nEnter Number of Attributes : ";
cin >> aN;
int attVal[qN][aN];
cout << "\nEnter Attribute Usage Values" << endl;
for(int n = 0; n < qN; n++) { //for looping in queries
cout << "\n\n***************** COLUMN " << n + 1 << " *******************\n\n";
for(int i = 0; i < aN; i++) { //for looping in Attributes
LOOP1:
cout << "Use(Q" << n + 1 << " , " << "A" << i + 1 << ") = ";
cin >> attVal[n][i];
cout << endl;
if((attVal[n][i] > 1) || (attVal[n][i] < 0)) {
cout << "\n\nTHE VALUE MUST BE 1 or 0 . Please Re-Enter The Values\n\n";
goto LOOP1; //if wrong input value
}
}
}
showAttributeUsage(attVal[qN][aN]);
cout << "\n\nYOUR ATTRIBUTE USAGE MATRIX IS\n\n";
getch();
return 0;
}
void showAttributeUsage(int att)
{
int n = 0, i = 0;
while(n != '\0') {
while(i != '\0') {
cout << att[n][i] << " ";
i++;
}
cout << endl;
n++;
}
}
I really suggest to use std::vector : live example
void showAttributeUsage(const std::vector<std::vector<int>>& att)
{
for (std::size_t n = 0; n != att.size(); ++n) {
for (std::size_t i = 0; i != att.size(); ++i) {
cout << att[n][i] << " ";
}
cout << endl;
}
}
And call it that way:
showAttributeUsage(attVal);
Looking at your code, I see no reason why you can't use std::vector.
First, your code uses a non-standard C++ extension, namely Variable Length Arrays (VLA). If your goal is to write standard C++ code, what you wrote is not valid standard C++.
Second, your initial attempt of passing an int is wrong, but if you were to use vector, your attempt at passing an int will look almost identical if you used vector.
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
typedef std::vector<int> IntArray;
typedef std::vector<IntArray> IntArray2D;
using namespace std;
void showAttributeUsage(const IntArray2D&);
int main()
{
int qN, aN;
cout << "Enter Number of Queries : ";
cin >> qN;
cout << "\nEnter Number of Attributes : ";
cin >> aN;
IntArray2D attVal(qN, IntArray(aN));
//... Input left out ...
showAttributeUsage(attVal);
return 0;
}
void showAttributeUsage(const IntArray2D& att)
{
for_each(att.begin(), att.end(),
[](const IntArray& ia) {std::copy(ia.begin(), ia.end(), ostream_iterator<int>(cout, " ")); cout << endl;});
}
I left out the input part of the code. The vector uses [] just like a regular array, so no code has to be rewritten once you declare the vector. You can use the code given to you in the other answer by molbdnilo for inputing the data (without using the goto).
Second, just to throw it into the mix, the showAttributeUsage function uses the copy algorithm to output the information. The for_each goes throw each row of the vector, calling std::copy for the row of elements. If you are using a C++11 compliant compiler, the above should compile.
You should declare the function like this.
void array_function(int m, int n, float a[m][n])
{
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
a[i][j] = 0.0;
}
where you pass in the dimensions of array.
This question has already been answered here. You need to use pointers or templates. Other solutions exists too.
In short do something like this:
template <size_t rows, size_t cols>
void showAttributeUsage(int (&array)[rows][cols])
{
for (size_t i = 0; i < rows; ++i)
{
std::cout << i << ": ";
for (size_t j = 0; j < cols; ++j)
std::cout << array[i][j] << '\t';
std::cout << std::endl;
}
}
You're using a compiler extension that lets you declare arrays with a size determined at runtime.
There is no way to pass a 2D array with such dimensions to a function, since all but one dimension for an array as a function parameter must be known at compile time.
You can use fixed dimensions and use the values read as limits that you pass to the function:
const int max_queries = 100;
const int max_attributes = 100;
void showAttributeUsage(int array[max_queries][max_attributes], int queries, int attributes);
int main()
{
int attVal[max_queries][max_attributes];
int qN = 0;
int aN = 0;
cout << "Enter Number of Queries (<= 100) : ";
cin >> qN;
cout << "\nEnter Number of Attributes (<= 100) : ";
cin >> aN;
cout << "\nEnter Attribute Usage Values" << endl;
for (int n = 0; n < qN; n++)
{
cout << "\n\n***************** COLUMN " << n + 1 <<" *******************\n\n";
for (int i = 0; i < aN; i++)
{
bool bad_input = true;
while (bad_input)
{
bad_input = false; // Assume that input will be correct this time.
cout << "Use(Q" << n + 1 << " , " << "A" << i + 1 << ") = ";
cin >> attVal[n][i];
cout << endl;
if (attVal[n][i] > 1 || attVal[n][i] < 0)
{
cout << "\n\nTHE VALUE MUST BE 1 or 0 . Please Re-Enter The Values\n\n";
bad_input = true;
}
}
}
}
cout << "\n\nYOUR ATTRIBUTE USAGE MATRIX IS\n\n";
showAttributeUsage(attVal, qN, aN);
getch();
return 0;
}
void showAttributeUsage(int att[max_queries][max_attributes], int queries, int attributes)
{
for (int i = 0; i < queries; i++)
{
for (int j = 0; j < attributes; j++)
{
cout << att[i][j] << " ";
}
cout << endl;
}
}
For comparison, the same program using std::vector, which is almost identical but with no size limitations:
void showAttributeUsage(vector<vector<int> > att);
int main()
{
cout << "Enter Number of Queries (<= 100) : ";
cin >> qN;
cout << "\nEnter Number of Attributes (<= 100) : ";
cin >> aN;
vector<vector<int> > attVal(qN, vector<int>(aN));
cout << "\nEnter Attribute Usage Values"<<endl;
for (int n = 0; n < qN; n++)
{
cout<<"\n\n***************** COLUMN "<<n+1<<" *******************\n\n";
for (int i = 0; i < aN; i++)
{
bool bad = true;
while (bad)
{
bad = false;
cout << "Use(Q" << n + 1 << " , " << "A" << i + 1 << ") = ";
cin >> attVal[n][i];
cout << endl;
if (attVal[n][i] > 1 || attVal[n][i] < 0)
{
cout << "\n\nTHE VALUE MUST BE 1 or 0 . Please Re-Enter The Values\n\n";
bad = true;
}
}
}
}
cout << "\n\nYOUR ATTRIBUTE USAGE MATRIX IS\n\n";
showAttributeUsage(attVal);
getch();
return 0;
}
void showAttributeUsage(vector<vector<int> > att);
{
for (int i = 0; i < att.size(); i++)
{
for (int j = 0; j < att[i].size(); j++)
{
cout << att[i][j] << " ";
}
cout << endl;
}
}
The Particular Logic worked for me. At last found it. :-)
int** create2dArray(int rows, int cols) {
int** array = new int*[rows];
for (int row=0; row<rows; row++) {
array[row] = new int[cols];
}
return array;
}
void delete2dArray(int **ar, int rows, int cols) {
for (int row=0; row<rows; row++) {
delete [] ar[row];
}
delete [] ar;
}
void loadDefault(int **ar, int rows, int cols) {
int a = 0;
for (int row=0; row<rows; row++) {
for (int col=0; col<cols; col++) {
ar[row][col] = a++;
}
}
}
void print(int **ar, int rows, int cols) {
for (int row=0; row<rows; row++) {
for (int col=0; col<cols; col++) {
cout << " | " << ar[row][col];
}
cout << " | " << endl;
}
}
int main () {
int rows = 0;
int cols = 0;
cout<<"ENTER NUMBER OF ROWS:\t";cin>>rows;
cout<<"\nENTER NUMBER OF COLUMNS:\t";cin>>cols;
cout<<"\n\n";
int** a = create2dArray(rows, cols);
loadDefault(a, rows, cols);
print(a, rows, cols);
delete2dArray(a, rows, cols);
getch();
return 0;
}
if its c++ then you can use a templete that would work with any number of dimensions
template<typename T>
void func(T& v)
{
// code here
}
int main()
{
int arr[][7] = {
{1,2,3,4,5,6,7},
{1,2,3,4,5,6,7}
};
func(arr);
char triplestring[][2][5] = {
{
"str1",
"str2"
},
{
"str3",
"str4"
}
};
func(triplestring);
return 0;
}

Overloading + operator with classes containing array pointers (C++)

I am currently writing a "Polynomial" class in order to practice Operator Overloading. I have successfully overloaded the stream extraction and insertion operators, but I am having some trouble with the "+" operator.
My class has a private pointer that proceeds to create an array in the constructor. I understand how one would overload the "+" operator with a complex number class, for example, but I'm getting confused with this program.
Guidance in finding a solution would be greatly appreciated.
Thank you.
#include<iostream>
#include<stdexcept>
using namespace std;
#ifndef POLYNOMIAL_H
#define POLYNOMIAL_H
class Polynomial
{
friend istream& operator>>(istream& in, Polynomial& p);
friend ostream& operator<<(ostream& out, const Polynomial& p);
public:
Polynomial(int = 10);
~Polynomial();
void assignExponent();
Polynomial operator+(const Polynomial& other);
private:
int SIZE;
int *exponents;
int *polyPtr; //***************
};
#endif
//CONSTRUCTOR
Polynomial::Polynomial(int arraySize)
{
if(arraySize > 0)
SIZE = arraySize;
else
{
cout << "Array size must be greater than 0. Program will now "
<< "Terminate..." << endl;
system("pause");
exit(0);
}
polyPtr = new int[SIZE]; //*********************
exponents = new int[SIZE];
for(int i = 0; i<SIZE; i++)
polyPtr[i] = 0;
assignExponent();
};
//DESTRUCTOR
Polynomial::~Polynomial() //******************
{
delete [] polyPtr;
};
//STREAM INSERTION
istream& operator>>(istream& in, Polynomial& p)
{
for(int i = 0; i<p.SIZE; i++)
{
in >> p.polyPtr[i]; //*************
}
return in;
};
//STREAM EXTRACTION
ostream& operator<<(ostream& out, const Polynomial& p)
{
int exponent;
for(int i = 0; i<p.SIZE; i++)
{
exponent = (p.SIZE - 1) - i;
if(p.polyPtr[i] != 1)
{
if(exponent > 0 && exponent != 1)
out << p.polyPtr[i] << "x^" << exponent << " + ";
if(exponent == 1)
out << p.polyPtr[i] << "x" << " + ";
if(exponent == 0)
out << p.polyPtr[i];
}
//In order to not display coefficient if = 1
else
{
if(exponent > 0 && exponent != 1)
out << "x^" << exponent << " + ";
if(exponent == 1)
out << "x" << " + ";
if(exponent == 0)
out << p.polyPtr[i];
}
}
return out;
};
//Assigns a value for exponent
void Polynomial::assignExponent()
{
for(int i = 0; i<SIZE; i++)
{
exponents[i] = (SIZE - 1) - i;
}
};
//OVERLOAD OF + OPERATOR
Polynomial Polynomial::operator+(const Polynomial& other)
{
Polynomial sum(SIZE);
int difference;
//If the first polynomial is larger
if (SIZE > other.SIZE)
{
difference = SIZE - other.SIZE;
for(int i = 0; i<SIZE; i++)
{
if(i - difference < 0)
sum.polyPtr[i] = polyPtr[i];
else
{
sum.polyPtr[i] = polyPtr[i] +
other.polyPtr[i - difference];
}
}
}
//If the second polynomial is larger **PROBLEM**
if(other.SIZE > SIZE)
{
difference = other.SIZE - SIZE;
for(int i = 0; i<other.SIZE; i++)
{
if(i - difference < 0)
sum.polyPtr[i] = other.polyPtr[i];
else
{
sum.polyPtr[i] = other.polyPtr[i] +
polyPtr[i - difference];
}
}
}
//If the polynomials are equal
if(SIZE == other.SIZE)
{
for(int i = SIZE-1; i >= 0; i--)
{
sum.polyPtr[i] = polyPtr[i] + other.polyPtr[i];
}
}
return sum;
};
int main()
{
int polySize;
//User enters a size for the first & second polynomial
cout << "Enter a size for the first polynomial: ";
cin >> polySize;
Polynomial pOne(polySize);
cout << "\nEnter a size for the second polynomial: ";
cin >> polySize;
Polynomial pTwo(polySize);
//User enters in values (Overload of >> operator
cout << "\n\nEnter in values for the first polynomial, "
<< "in the format - (x x x x): " << endl;
cin >> pOne;
cout << "\nEnter in values for the second polynomial, "
<< "in the format - (x x x x): " << endl;
cin >> pTwo;
//Overload << operator for output
cout << "\nPolynomial 1 is: " << pOne << endl
<< "Polynomial 2 is: " << pTwo << endl;
Polynomial pThree = pOne + pTwo;
cout << "\nAfter being added together, the new polynomial is: "
<< pThree << endl;
system("pause");
}
I have updated my current code because I did not think opening another question would be the best way to go. Anyway, in trying to line up my polynomial's to be added, I've partially succeeded. The only problem that arises is when the second polynomial, pTwo, is larger than the first. I've labeled the section of code, PROBLEM. Thanks in advance.
I guess the + should write like below:
class Polynomial
{
// ...
Polynomial operator+(const Polynomial& other);
// ...
};
Polynomial Polynomial::operator+(const Polynomial& other)
{
Polynomial sum(SIZE);
for(int i = 0; i< SIZE; i++)
{
sum.polyPtr[i] = polyPtr[i] + other.polyPtr[i];
}
return sum;
}