The code I wrote compiles without errors thus I don't know the reason an error is ocurring.
#pragma once
class Macierz
{
public:
class Wiersz
{
public:
int *tab;
int dlugosc;
Wiersz(int d);
};
int x;
int y;
Wiersz *wiersze;
public:
Macierz(int m, int n);
Macierz(Macierz &m);
Macierz & operator+(Macierz &m);
Macierz & operator-(Macierz &m);
Macierz & operator*(Macierz &m);
Macierz & operator=(Macierz &m);
int& operator()(int x, int y);
string to_String();
};
#include "stdafx.h"
#include "Macierz.h"
Macierz::Macierz(int _x, int _y) :x(_x), y(_y)
{
Wiersz **tab = new Wiersz*[_x];
for (int i = 0; i < x; i++)
tab[i] = new Wiersz(_y);
wiersze = *tab;
}
Macierz::Macierz(Macierz &m) :Macierz(m.x, m.y)
{
for (int i = 0; i < x; i++)
for (int j = 0; j < y; j++)
wiersze[i].tab[j] = m.wiersze[i].tab[j];
}
Macierz & Macierz::operator+(Macierz &m)
{
if (x != m.x || y != m.y) throw "Macierze maja rozne rozmiary";
Macierz *temp = new Macierz(m);
for (int i = 0; i < x; i++)
for (int j = 0; j < y; j++)
(*temp).wiersze[i].tab[j] += wiersze[i].tab[j];
return *temp;
}
Macierz & Macierz::operator-(Macierz &m)
{
if (x != m.x || y != m.y) throw "Macierze maja rozne rozmiary";
Macierz *temp = new Macierz(m);
for (int i = 0; i < x; i++)
for (int j = 0; j < y; j++)
(*temp).wiersze[i].tab[j] -= wiersze[i].tab[j];
return *temp;
}
Macierz & Macierz::operator*(Macierz &m)
{
Macierz *temp;
if (x == m.y)
{
temp = new Macierz(m.x, y);
for (int i = 0; i < (*temp).x; i++)
for (int j = 0; j < (*temp).y; j++)
for (int l = 0; l < m.y; l++)
(*temp).wiersze[i].tab[j] += wiersze[i].tab[l] * m.wiersze[l].tab[j];
}
else if (y == m.x)
{
temp = new Macierz(x, m.y);
for (int i = 0; i < (*temp).x; i++)
for (int j = 0; j < (*temp).y; j++)
for (int l = 0; l < y; l++)
(*temp).wiersze[i].tab[j] += wiersze[i].tab[l] * m.wiersze[l].tab[j];
}
else throw "Rozmiary macierzy sie nie zgadzaja";
return *temp;
}
Macierz & Macierz::operator=(Macierz &m)
{
for (int i = 0; i < x; i++)
for (int j = 0; j < y; j++)
wiersze[i].tab[j] = m.wiersze[i].tab[j];
return *this;
}
int& Macierz::operator()(int x, int y)
{
return wiersze[x].tab[y];
}
Macierz::Wiersz::Wiersz(int i)
{
dlugosc = i;
tab = new int[dlugosc];
}
string Macierz::to_String()
{
std::ostringstream str;
str << "|";
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
str << wiersze[j].tab[i] << ",";
str << "\b|\n";
}
return str.str();
}
Using constructor in main doesn't crash the program:
Macierz m1(1,1);
However there seems to be a problem with accesing to certain data field, e.g.
m1(0,0) = 1;
(at least this is a code line at which some yellow arrow points)
Program is used for operations on matrix(+, -, *). I wrote a program in similar fashion for euclidean vector operations which works perfectly.
Thanks for help in advance.
There are a lot of issues in your code that will result in problems:
Macierz(int _x, int _y)
doesn't work like you think it does. Only wiersze[0]
will be valid after it finishes and any non-zero index will access unknown memory. The issue is really with your design of your 2D matrix class. I would get rid of the manually managed memory and just use a 2D vector vector<vector<int>>
or even just a flat 1D vector and manage the index manually. Macierz(Macierz &m)
doesn't allocate memory for the new matrix and thus you are writing to unknown memory.return *this;
for such operators. See this question for more details on operator overloading.Macierz::operator=(Macierz &m)
doesn't check if the matrix is the same size or not. If it isn't the same size you'd need to destroy and reallocate the matrix.Macierz::operator()(int x, int y)
doesn't check the input indexes which may be on purpose but you may consider throwing an exception like with your other methods.vector<>
you wouldn't need one.If you really need/want to implement a 2D matrix class from scratch you can search online for a large variety of existing code, like this one, as examples of what to do.