c++first-chance-exception

First chance exception without compiling errors


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.


Solution

  • There are a lot of issues in your code that will result in problems:

    1. Your constructor 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.
    2. Your copy constructor Macierz(Macierz &m) doesn't allocate memory for the new matrix and thus you are writing to unknown memory.
    3. All your binary operators (+, -, *) allocate a new object and return it which will result in leaked memory. The canonical way is usually to modify the object and just return *this; for such operators. See this question for more details on operator overloading.
    4. Your copy operator 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.
    5. Your 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.
    6. You have no destructor which will result in leaked memory, although if you use a 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.