I want to implement a Matrix class. I coded an array of arrays of pointers. When I set the values of each element of the array to 0 with a for loop, it works fine (apparently). But when I try to declare a function of my class (setvalues) to take the values of a 1D array and store them in the matrix, theres a problem with the arguments. I am not sure how to declare a function that takes a dynamic array as argument.
#include<iostream>
using namespace std;
class Matrix{
int rows, columns, numE;
double *mData=new double[numE];
public:
double** matrix;
Matrix(int,int);
setmatrix();
setvalues(double);
};
Matrix::Matrix(int x, int y){
rows=y;
columns=x;
matrix=new double*[columns];
for(int i = 0; i < columns; ++i){
matrix[i]=new double[rows];
}
}
Matrix::setmatrix(){
for(int i=0;i<rows;i++){
for(int j=0;j<columns;j++){
matrix[i][j]=0.0;
cout<<matrix[i][j]<<endl;
}
}
}
Matrix::setvalues(double mData[]){
for(int i=0;i<rows;i++){
for(int j=0;j<columns;j++){
matrix[i][j]=mData[i];
}
}
}
int main(){
Matrix AA(2,2);
AA.setmatrix();
//AA.setvalues();
for(int i=0;i<2;i++){
for(int j=0;j<2;j++){
cout<<AA.matrix[i][j] << endl;
}
}
cout<< AA.matrix << endl;
delete [] AA.matrix;
return 0;
}
PS: I don't want to use vector or smart pointers. Also if you have any feedback about my code regarding functionaity, readability and if you know a smarter way to do it please tell me.
Related
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.
Very new beginner here and I'm at the end of my rope with this assignment and would really appreciate any help :). Apologies in advance for the length.
I'm having some trouble with retrieving and setting values for my dynamically allocated 2D array. I have a class, defined below, that should construct a 2D array, at which point I need the option to set a value to a given point in the array and also to retrieve a value at a given point.
I ran the debugger, and got as far as to figure out that I have a segmentation fault when the setValue function runs. Can anyone help me understand what I'm doing wrong? As a beginner, the easier terms the better :). Thank you kindly in advance.
#include <iostream>
using namespace std;
class array2D
{
protected:
int xRes;
int yRes;
float ** xtable;
public:
array2D (int xResolution, int yResolution);
~array2D() {}
void getSize(int &xResolution, int &yResolution);
void setValue(int x,int y,float val);
float getValue(int x,int y);
};
array2D::array2D(int xResolution, int yResolution)
{
xRes=xResolution;
yRes=yResolution;
float ** xtable = new float*[yResolution];
for(int i=0;i < yResolution;i++)
{
xtable[i] = new float[xResolution];
}
for(int i=0;i < yRes;i++)
{
for(int j=0;j < xRes;j++)
{
xtable[i][j]=45;
}
}
}
void array2D::getSize(int &xResolution, int &yResolution)
{
xResolution=xRes;
yResolution=yRes;
cout << "Size of Array: " << xResolution << ", " << yResolution << endl;
}
void array2D::setValue(int x,int y,float val)
{
xtable[x][y] = val;
}
float array2D::getValue(int x,int y)
{
return xtable[x][y];
}
int main()
{
array2D *a = new array2D(320,240);
int xRes, yRes;
a->getSize(xRes,yRes);
for(int i=0;i < yRes;i++)
{
for(int j=0;j < xRes;j++)
{
a->setValue(i,j,100.0);
}
}
for(int i=0;i < yRes;i++)
{
for(int j=0;j < xRes;j++)
{
cout << a->getValue(i,j) << " ";
}
cout << endl;
}
delete[] a;
}
The line
float ** xtable = new float*[yResolution];
creates a function local variable. The member variable of the class still remains uninitialized. That's not what you want. To allocate memory and assign it to the member variable, remove the type specifier from that line. Just use:
xtable = new float*[yResolution];
Also, you need to switch the use of yResolution and xResolution in those lines. Otherwise, getValue and setValue will be using the indices incorrectly.
Swap the use of xResolution and yResolution in the following lines so that you use:
float ** xtable = new float*[xResolution];
for(int i=0;i < xResolution;i++)
{
xtable[i] = new float[yResolution];
}
Swap the use of xRes and yRes in the following lines so that you use:
for(int i=0;i < xRes;i++)
{
for(int j=0;j < yRes;j++)
{
xtable[i][j]=45;
}
}
Since your class acquires resources using dynamic memory allocation, you should read up on The Rule of Three and update your class accordingly.
int r,c;
cin>>r>>c;
int** p=new int*[r];
for(int i=0;i<r;i++) {
p[i]=new int[c];
}
for(int i=0;i<r;i++) {
delete [] p[i];
}
delete [] p;
Using this code you can create a 2D Dynamic Array in C++ which would allocate the memory of this array in the Heap Memory.
When I put a number in flag[1][2], I will automatically put that same number in flag[2][0].
Why?
#include <iostream>
using namespace std;
void inicializarFlag(void);
void imrpimeflag(void);
int flag[2][2];
int main(){
int i, j, escolha;
inicializarFlag();
cout<<"digite as posicoes e o valor: "<<endl;
cin>>i;
cin>>j;
cin>>escolha;
flag[i][j] = escolha;
imrpimeflag();
return 0;
}
void inicializarFlag(void){
for (int i=0; i<=2; i++){
for(int j=0; j<=2; j++){
flag[i][j] = 0;
}
}
}
void imrpimeflag(void){
for (int i=0; i<=2; i++){
for(int j=0; j<=2; j++){
cout<<"["<<i<<"]["<<j<<"]: "<<flag[i][j]<<endl;
}
}
}
When you initialize the array int flag[2][2], you are initializing a 2x2 array, not a 3x3 array. Since arrays are zero indexed, flag[2][0] places an int in the zeroth column of the third row of the 2x2 flags array, which is out of bounds. The behavior of placing an element out of the bounds of an array is undefined, and can lead to problems like you describe.
Declare int flag[3][3] and the code should work.
I want to initialize values of 2-D array to 0. But it seems not to work.
Can I initialize values of my **array in constructor to be 0. If yes the How.
My code is.
#include <iostream>
using namespace std;
int main(){
int row, col;
cin>>row;
cin>>col;
int **array=new int*[row];
for (int i=0; i<row; i++){
array[i]=new int[col];
}
for (int i=0; i<row;i++){
for (int j=0; j<col; j++){
array[i][j]={'0'};
cout<<array[i][j]<<" ";
}
cout<<endl;
}
}
Further can someone explain if I have to replace ith elem from the array with some other element, how would I deal with memory allocation.
You probably want array[i][j]=0;. Why were you using the char type '0'?
However, there is an easier way: array[i]=new int[col]();, just add () to value initialize each column.
There also is a better way:
std::vector<std::vector<int>> array(row, std::vector<int>(col));
For your first comment, you would need to create a new array with the new size, copy over all the data, and the delete your old 2-d array.
For your second comment, here is an example:
struct A
{
int **array;
A(int row, int col) : array(new int*[row])
{
for (int i=0; i < row; i++)
{
array[i]=new int[col]();
}
}
};
PS: You can save yourself a lot of work by using std::vector.
this codes works on gcc
#include <iostream>
using namespace std;
int main(){
int row, col;
cin>>row;
cin>>col;
int **array=new int*[row];
for (int i=0; i<row; i++){
array[i]=new int[col];
}
for (int i=0; i<row;i++){
for (int j=0; j<col; j++){
array[i][j]=0;
cout<<array[i][j]<<" ";
}
cout<<endl;
}
}
to replace ith element of the array with some other element we can do something lyk
int *aa = new int[p];
swap(array[i], aa)
but for this to work logically correct u need to make sure that p >= size of the array array[i] is pointing to. In most of our use cases we have them equal.
You can try something like this:-
class A
{
public:
A():my2DArray() {0}
private:
B* my2DArray[max1][max2];
};
I've tried many time to pass the array to a function then do some calculation such as getting the total of the columns, the problem is I don't know how to call the result form the function, usually I get errors.
this is just one code I'm trying to solve it from yesterday :
#include <iostream>
using namespace std;
//prototype
int get_total(int whatever[][2], int row);
int main ()
{
const int row=2;
const int col=3;
int marks[row][col];
// this is prompt the user to input the values
for (int i=0; i<row;i++)
{
for (int p=0; p<col; p++)
{
cin >> marks[i][p];
}
cout << endl;
}
// this is just display what the user input as a table
for (int x=0; x< row ; x++)
{
for (int y=0; y<col ; y++)
{
cout << marks[x][y] << " ";
}
cout << endl;
}
int sum;
// this is the most important thing I want to know,
// how to call the function :(
sum=get_total(marks,row);
return 0;
}
// to get the total of each columns
const int row=3;
// not sure if the declaration is correct or not :(
int get_total(int whatever[][2], int row)
{
for (int i=0; i < 2; i++)
{
for (int p=0; p < 3; p++)
int total=0;
//this line is completly wrong, How can I calculate the total of columns?
total+=get_total[2][p];
}
// do we write return total ?
// I'm not sure because we need the total for each column
return total;
}
sorry for the mess, and I appreciate any help to explain passing the multidimensions arry to a function as parameter and how to call the function>
Arrays decay to pointers when calling functions.
You can do 2 things:
Pass the number of lines and columns as arguments to the function.
Use std::vector instead. I suggest you take a look at it, it'll do the trick and you'll learn something new and very useful.
Also, your function should do this:
int get_total(int** whatever)
{
//total is 0 at the beginning
int total=0;
for (int i=0; i < 2; i++)
{
for (int p=0; p < 3; p++)
//go through each element and add it to the total
total+=whatever[i][p];
}
return total;
}
This will return the total for the whole matrix, I'm assuming that's what you mean by getting the total of the columns
int marks[row][col]
This means that marks has type int[2][3].
int get_total(int whatever[][2], int row);
You've however declared get_total to accept an int(*)[2]. int[2][3] can decay to int(*)[3] but that is not compatible with int(*)[2], hence why you can't pass marks to get_total. You can instead declare get_total to accept an int(*)[3]:
int get_total(int whatever[][3], int row);
// equivalent to:
int get_total(int (*whatever)[3], int row);
If you instead decide to declare get_total to accept an int** or an int*, then you can't legally pass marks to it in the former case, and you can't legally iterate over the whole multidimensional array in the latter. Consider not using arrays, it's simpler this way.