Status końcowy

0

Witam czy wie ktoś może co dokładnie oznacza "Proces zakończono z kodem -1073741819" ?

5

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.

0
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 ];

3

Bez kodu niby ciężko, ale pobawmy się we wróżkę: niepoprawnie implementujesz rule of three/five/zero. Lektura konieczna:

0
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;
}
3

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...

2

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";
    }
}


0

Problem już rozwiązany ! Dzięki wszystkim za odpowiedzi !

1 użytkowników online, w tym zalogowanych: 0, gości: 1