c++ using "indexing" over a 2D matrix, under this structure - c++

don't know why but i get an error: after this structure i can't index the matrix, so i cant use the "indexing method" over the defined matrix.Can anyone tell me why? or how to fix it?
Header:
const int days=31;
const int exp=6;
struct Array{
int days;
int exp;
int **M;
};
Constuctor:
void constr(Array loc){
//Construct of 31*6 Matrix, were 31 nr. of days and 6 specific types:
//0-HouseKeeping, 1-Food, 2-Transport, 3-Clothing, 4-TelNet, 5-others
loc.days = days;
loc.exp = exp;
loc.M = new int*[loc.days];
for(int i=0; i<loc.days;i++ ){
loc.M[i] = new int[loc.exp];
for (int j = 0; j< loc.exp; j++){
loc.M[i][j] = 0;
}
}
}
Controller.cpp
void add(int cant,int tip, Array M){
//Adds to current day the amount to a specific type
currDay();
M[currentDay][tip] += cant; ////////////error
}
void insert(int zi,int tip,int cant, Array M){
//Adds to current day the amount to a specific type
M[zi][tip] = cant; ///////////error
}
void removeDay(int day, Array M){
for(int i = 0; i<6; i++)
M[day][i] = 0; ///////////error
//zi and tip ~ day type... for easier read.
//i need to manage the expenses of a family in a month doesn't matter which
ERROR: error: no match for 'operator[]'
UI(where constructor is used):
int main(){
Array M;
constr(M);
printMenu();
return 0;
}

You're not accessing the member:
M.M[currentDay][tip]
instead of
M[currentDay][tip]
Or you could define operator [] for your struct:
struct Array{
int days;
int exp;
int **M;
int*& operator[] (int idx) { return M[idx]; }
};

You are trying to call operator[] on the type array. You need to get the pointer member first.
M.M[day][i];
That said: You are not writing C++ but some obscure form of bad C. You might want to have a look at the book list and read one of them before pursuing coding any further.

You have at least two problems:
The first is that you are using the actual structure as the array, which wont work. Use e.g. M.M[day][i].
The second is that when you create the array, you pass the structure by value, this means it will be copied to a local variable in the constr function and the data will not be available in the function calling constr. Pass it as a reference instead, i.e. void constr(Array &loc).
The second problem can also be solved by using a constructor in the structure, instead of a separate function:
const int DAYS=31;
const int EXP=6;
struct Array{
int days;
int exp;
int **M;
// Constructor, called when an instance of structure/class is created
Array(){
days = DAYS;
exp = EXP;
M = new int*[days];
for(int i=0; i<days;i++ ){
M[i] = new int[exp];
for (int j = 0; j< exp; j++){
M[i][j] = 0;
}
}
}
// Destructor, called when structure/class is destroyed
~Array(){
if(M){
for(int i=0;i<days;i++){
if(M[i])
delete [] M[i];
}
delete [] M
}
}
// Copy constructor, called when instance of structure/class is copied
Array(const Array &array){
days = array.days;
exp = array.exp;
M = new int*[days];
for(int i=0; i<days;i++ ){
M[i] = new int[exp];
for (int j = 0; j< exp; j++){
M[i][j] = array.M[i][j];
}
}
}
};

Related

Question regarding initialization of an array

My problem:
I have the following piece of code that is a wrapper for 2D square matrices in order to transpose them and print them. I cannot understand why we can write this:
arrayNN(T DATA[N][N]){
n = N;
data = DATA; }
In particular this line of code:data = DATA;.
My thoughts:
As far as i know, in C/C++ you cannot give the values of a matrix to another matrix. For example this piece of code doesn't work, no matter how we write the definition of b:
double array[3][3] = { {11,12,13},{21,22,23},{31,32,33}};
//only one definition
//double **b;
//double *b[3]
double b[3][3];
b = array;
Code: It works.
#include <iostream>
using namespace std;
template <typename T, size_t N>
class arrayNN {
private:
int n;
T (*data)[N]; # a vector of N elements of pointers to datatype T = 2d matrix
public:
arrayNN(): n(N), data(NULL) {};
arrayNN(T DATA[N][N]){
n = N;
data = DATA;
}
void print(ostream &out){
for(int i = 0;i<N;i++){
for(int j=0;j<N; j++){
cout << data[i][j] << '\t';
}
cout << endl;
}
}
void transpose(){
for(int i = 0;i<N;i++){
for(int j=0;j<i; j++){
T temp = data[i][j];
data[i][j] = data[j][i] ;
data[j][i] = temp;
}
}
}
};
int main(){
double array[3][3] = { {11,12,13},{21,22,23},{31,32,33}};
arrayNN<double,3> A(array);
A.print(cout);
A.transpose();
A.print(cout);
return 0;
}
T (*data)[N]; # a vector of N elements of pointers to datatype T = 2d matrix
No, data is not a vector or an array. Instead it is a pointer to an array of size N with elements of type T.
This means that when you wrote data = DATA; you're actually assigning the pointer DATA to the pointer data. Note that the function parameter DATA is a pointer and not an array. You can refer to What is array to pointer decay? for seeing why DATA is a pointer.

c++ swapping content of array - Selection Sort

I'm new to C++. I was attempting to write a function for selection sort the following way.
void selection_sort(int* m[], int array_size) {
for (int i = 0; i < array_size; i++)
int min_ind = i;
for (int j = i+1; j < array_size; j++){
if (m[min_ind] > m[j]){
min_ind = j;
}
}
int temp = *m[i];
*m[i] = *m[min_ind];
*m[min_ind] = temp;
}
}
Within main, the array is defined as:
int *sel_nums = new int[n];
And I'm calling selection sort in main:
selection_sort( &sel_nums, x );
I keep getting an error that says:
Segmentation fault (core dumped)
Does anyone have any input on why this keeps happening?
You allocated dynamically an array of objects of the type int.
int *sel_nums = new int[n];
This array you are going to pass to the function selection_sort. So the function declaration will look at ;east like
void selection_sort( int m[], int array_size );
The compiler implicitly adjust the parameter having the array type to pointer to the array element type. That is the above declaration is equivalent to
void selection_sort( int *m, int array_size );
So the function can be called like
selection_sort( sel_nums, n );
To swap two elements of the array within the function you can write
if ( min_ind != i )
{
int temp = m[i];
m[i] = m[min_ind];
m[min_ind] = temp;
}
Or you could use the standard C++ function std::swap like
#include <utility>
//...
if ( min_ind != i )
{
std::swap( m[i], m[min_ind] );
}

c++ Dynamic Allocation of 2D Array Class

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.

dynamic allocation of int array in c++ and assigning value

I am new to c++ and i was trying to do folloing two things without help of std::vector( This was done earlier)
Define an array of integer and the size of array is not known to me.
Pass this array into another function and output all the values stored in array.
int _tmain()
{
int* a = NULL;
int n;
std::cin >> n;
a = new int[n];
for (int i=0; i<n; i++) {
a[i] = 0;
}
testFunction(a,n);
delete [] a;
a = NULL;
}
void testFunction( int x[], int n)
{
for(int i =0;i<n;++n)
{
std::cout<<x[i];
}
}
But i can see that its not allocating memory of 10 bytes and all the time a single memory is filled up with 0.
Can anyone please help me if i am lacking something ? Or is there any alternative way for this apart from vector.
Thanks in Advance
I modified with one thing as i realized that i put ++n instead of i
int _tmain()
{
int* a = NULL;
int n;
std::cin >> n;
a = new int[n];
for (int i=0; i<n; i++) {
a[i] = i;
}
testFunction(a,n);
delete [] a;
a = NULL;
}
void testFunction( int x[], int n)
{
for(int i =0;i<n;++i)
{
std::cout<<x[i];
}
}
I’m not sure I understand all yours problems but the typo
for(int i =0;i<n;++n) in testFunction led to a very long loop.
Write:
for(int i =0;i<n;++i)
this print yours n "0"

Deleting a doublepointer (matrix)

I am solving a quantum-mech problem which requires me to find some eigenvalues by manipulating some matrices. The specifics of this problem is not relevant, I just need help with the c++ problem, I am new to this language and after a couple of hours I figured any more attempts at solving it myself would be futile and so I turn to you for help.
I have this problem where glibc detects an error at the end of my program and I cannot deallocate properly, it is far too big to copypaste here so I will just replicate the part that actually gives the error.
void hamiltonian(int, double **&);
int i,j;
int main()
{
int N = 1000; double **A;
hamiltonian(N, A);
//Physics here
.
.
.
.
.
//Delete
for(i=0; i<N; i++){delete []A[i];}
delete []A;
return 0;
}
void hamiltonian(int N, double **&A)
{
A = new double *[N];
for(i=0; i<N; i++)
{
A[i] = new double[N];
for(j=0; j<N; j++)
{
if(i==j)A[i][j] = 2;
if(i==j+1 || i==j-1){A[i][j] = 1;}
}
}
}
According to my professor I have to deallocate in the same function as I allocate but I didn't even think about deallocation after being nearly done with my project and so I have to rewrite a lot of code, the problem is that I cannot deallocate A inside the hamiltonian function as I need it in other functions (inside //Physics).
Surely there must be a way around this? Might sound a bit ignorant of me but this sounds like a less efficient design if I have to deallocate in the same function as I allocate.
According to my professor I have to deallocate in the same function as I allocate
That is pure silliness. Sometimes (almost always) you need to use the allocated struct outside the function. Definitely false for objects, since constructors and destructors are different functions.
Any way, you can get away without using classes, if you make a Matrix struct and associated newMatrix and deleteMatrix functions :)
#include <cstddef>
#include <iostream>
using namespace std;
struct Matrix
{
int n;
int m;
double** v;
};
Matrix newMatrix (int n, int m)
{
Matrix A;
A.n = n;
A.m = m;
A.v = new double*[n];
for( int i = 0; i < n; i++ ){
A.v[i] = new double[m];
}
return A;
}
Matrix newHamiltonianMatrix (int n, int m)
{
Matrix A = newMatrix(n, m);
for( int i = 0; i < A.n; i++ ){
for( int j = 0; j < A.m; j++ ){
A.v[i][j] = 0.0;
if( i == j ){
A.v[i][j] = 2.0;
}
if( i == j + 1 or i == j - 1 ){
A.v[i][j] = 1.0;
}
}
}
return A;
}
void deleteMatrix (Matrix A)
{
for( int i = 0; i < A.n; i++ ){
delete [] A.v[i];
}
delete [] A.v;
A.v = NULL;
}
int main ()
{
Matrix A = newHamiltonianMatrix(10, 20);
for( int i = 0; i < A.n; i++ ){
for( int j = 0; j < A.m; j++ ){
cout << A.v[i][j] << " ";
}
cout << endl;
}
deleteMatrix(A);
}
delete A;
Needs to be
delete[] A;
If you new[] it, you MUST delete[] it. Also, use a vector- they take care of themselves.
vector<vector<double>> matrix;
There are couple of problems with your code.
(1) You are not allocating memory to the pointer members of A. i.e. A[i] are not allocated with new[]. So accessing them is an undefined behavior.
(2) You must do delete[] for a pointer if it was allocated with new[]. In your other function delete A; is wrong. Use delete[] A;
(3) Using new/new[] is not the only way of allocation. In fact you should use such dynamic allocation when there is no choice left. From your code it seems that you are hard coding N=1000. So it's better to use an 2D array.
const int N = 1000; // globally visible
int main ()
{
double A[N][N];
...
}
void hamiltonian (double (&A)[N][N])
{
...
}