Witam czy wie ktoś może co dokładnie oznacza "Proces zakończono z kodem -1073741819" ?
Wbrew pozorom to dość dużo mówi: ta wartość, rozumiana jako 32-bitowa liczba bez znaku to c0000005
, a błąd c0000005
oznacza Access Violation - gdzieś masz zapewne wyjście poza zakres tablicy/zaalokowanej pamięci/używasz wskaźnika do uwolnionej pamięci.
kq napisał(a):
Wbrew pozorom to dość dużo mówi: ta wartość, rozumiana jako 32-bitowa liczba bez znaku to c0000005
, a błąd c0000005
oznacza Access Violation - gdzieś masz zapewne wyjście poza zakres tablicy/zaalokowanej pamięci/używasz wskaźnika do uwolnionej pamięci.
Dzięki za odpowiedź! Podejrzewałem właśnie, że chodzi o coś związanego z uwolnioną pamięcią gdyż komunikat taki otrzymuje podczas użycia przeciążonego operator=, dla którego to wartości pochodzą z innego obiektu zwracanego przez przeciążony operator* tzn. jest to sytuacja np: A.operator=(B.operator*(C)); [ A = B * C ];
Bez kodu niby ciężko, ale pobawmy się we wróżkę: niepoprawnie implementujesz rule of three/five/zero. Lektura konieczna:
kq napisał(a):
Bez kodu niby ciężko, ale pobawmy się we wróżkę: niepoprawnie implementujesz rule of three/five/zero. Lektura konieczna:
Kod:
class Macierz
{
public:
float** tab;
// Konstruktor
Macierz() {
tab = new float *[2];
for (int i = 0; i < 2; i++)
tab[i] = new float[2];
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
tab[i][j] = 0;
}
};
// Destruktor
~Macierz()
{
for (int i = 0; i < 2; i++)
delete[] tab[i];
delete[] tab;
};
// Metody
void Set(int A, int B, float C);
void Get();
// Przeciazenie operatorow
Macierz& operator=(const Macierz& M)
{
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
tab[i][j] = M.tab[i][j];
}
return *this;
}
Macierz operator*(const Macierz& m)
{
Macierz M;
M.tab[0][0] = m.tab[0][0] * tab[0][0] + m.tab[0][1] * tab[1][0];
M.tab[0][1] = m.tab[0][0] * tab[0][1] + m.tab[0][1] * tab[1][1];
M.tab[1][0] = m.tab[1][0] * tab[0][0] + m.tab[1][1] * tab[1][0];
M.tab[1][1] = m.tab[1][0] * tab[0][1] + m.tab[1][1] * tab[1][1];
return M;
}
};
// Metoda Set
void Macierz::Set(int A, int B, float C)
{
tab[A][B] = C;
}
//Metoda Get
void Macierz::Get()
{
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
std::cout << tab[i][j]<<" ";
std::cout << "\n";
}
}
int main()
{
Macierz A,B,C;
A.Set(0, 0, 1.0);
A.Set(0, 1, 2.0);
A.Set(1, 0, 3.0);
A.Set(1, 1, 4.0);
B = A;
B.Set(0, 0, 5.0);
A.Get();
std::cout << "\n";
B.Get();
std::cout << "\n";
C = A * B; // Tutaj powstaje problem
return 0;
}
No i trafiłem, nie definiujesz konstruktora kopiującego, a w tym przypadku musisz. Lekturę konieczną dałem wcześniej.
Trochę rozbudowując
C = A * B;
jest mniej więcej ekwiwalentne dla tego:
{
Macierz m = A * B;
C = m;
}
Konstruujesz temp
za pomocą konstruktora kopiującego utworzonego przez kompilator, który w tym przypadku jest głupiutki i nie wie, że nie powinien kopiować
Chociaż jak teraz myślę to chyba od C++17 to powinno zostać zoptymalizowane i "działać", pomimo że nie jest specjalnie poprawne...
Kilka słów o szczegółach
- wielokrotnie użyta stała 2 to źle. Daj w klasie const int N=2;
- Set by o wiele ładniejszy był w formie operatora, ale to ciut ambitniejsze.
- jak będziesz realizował coś ambitniejszego, używaj double zamiast float. Większa dokładność, i na większości architektur nie będzie wolniejsze, a na niektórych może być szybsze.
- metoda void Get która drukuje, bardzo "nowatorskie". Nazwy powinny oddawać rzeczywistą akcję funkcji. Zmień na Print albo coś w tym rodzaju
Ja bym dał strumień jako argument
void Macierz::Print(std::ostream & ostr)
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
ostr << tab[i][j]<<" ";
ostr << "\n";
}
}
Problem już rozwiązany ! Dzięki wszystkim za odpowiedzi !