tygryseks Temat założony przez niniejszego użytkownika |
[C++] Zawieszenie programu przy wywołaniu destruktora » 2012-11-13 22:27:45 Witam, mam do napisania taki program: "Utwórz klasę z macierzą double o wymiarach 2*2. Klasa powinna zawierać m.in. konstruktor inicjujący macierz, funkcje Dodaj_macierz(), Odejmij_macierz(), Pomnóż_macierz(), Wypisz_macierz()." Program napisałem ale mam problem z destruktorem. Gdy destruktor zakomentuję to program działa ok, oblicza ok, jednak gdy destruktor nie jest zakomentowany to program się zawiesza przy wykonaniu. Nie wiem dlaczego tak się dzieje, próbowałem na różne sposoby przerabiać program ale bezskutecznie, wiem że wiele jest na forum o tablicach dynamicznych ale niestety nie znalazłem informacji które były by dla mnie pomocne. Piszę w DevC++ Aby kod był krótszy umieszczam tylko funkcję dodawania macierzy. #include <iostream> #include <stdio.h> #include <cstdlib>
using namespace std;
class Macierz { private: int m_size; double ** tab_m; public: Macierz( int = 2 ); void wypelnij_macierz(); void wypisz_macierz(); Macierz dodaj_macierz( Macierz m2 ); };
Macierz::Macierz( int size ) { m_size = size; tab_m = new double *[ m_size ]; for( int i = 0; i < m_size; i++ ) tab_m[ i ] = new double[ size ]; }
void Macierz::wypelnij_macierz() { for( int i = 0; i < m_size; i++ ) { for( int j = 0; j < m_size; j++ ) { cout << "Wprowadz wartosc do macierzy [ " << i << " ][ " << j << " ] : "; cin >> tab_m[ i ][ j ]; } } }
void Macierz::wypisz_macierz() { for( int i = 0; i < m_size; i++ ) { for( int j = 0; j < m_size; j++ ) { cout << tab_m[ i ][ j ] << " "; } cout << endl; } }
Macierz Macierz::dodaj_macierz( Macierz m2 ) { cout << "Dodaje macierze \n"; cout << "Wynik dodawania: \n"; Macierz suma; for( int i = 0; i < m_size; i++ ) { for( int j = 0; j < m_size; j++ ) { suma.tab_m[ i ][ j ] = tab_m[ i ][ j ] + m2.tab_m[ i ][ j ]; } } return suma; }
int main() { Macierz m1, m2, suma; m1.wypelnij_macierz(); cout << endl; m2.wypelnij_macierz(); cout << endl; cout << "Podane dane: \n\n"; m1.wypisz_macierz(); cout << endl; m2.wypisz_macierz(); cout << endl; suma = m1.dodaj_macierz( m2 ); cout << endl; suma.wypisz_macierz(); cout << endl; system( "PAUSE" ); return 0; }
kurde nie wiem jak zrobić żeby ten kod był w ramce |
|
akwes |
» 2012-11-13 22:40:36 Kod umieszczaj w tagach [cpp] kod [/cpp] |
|
ison |
» 2012-11-13 22:44:55 W dodaj_macierz zwracasz kopię obiektu tymczasowego, nie masz przeciążonego operatora = z kopiowaniem dynamicznej zawartości więc kopia obiektu będzie zawierała wskaźnik na tę samą macierz co obiekt tymczasowy, a ta macierz już nie istnieje bo została wyrzucona w destruktorze. |
|
crash |
» 2012-11-13 22:45:23 <bzdura>..</bzdura> Ison ma rację. I jeszcze jedno, na przyszłość: //kod na jedna linijke
/* przepis na kod na wiele linijków */
;) PS:piłeś, nie programuj |
|
tygryseks Temat założony przez niniejszego użytkownika |
» 2012-11-13 22:51:22 Niestety z tym destruktorem pojawia się błąd: [Error] definition of implicitly-declared 'Macierz::~Macierz()'
Co do komentarzy to wiem o co chodzi ale tak komentuje mi Dev Gdy zaznaczę fragment kodu -tak dla mnie jest szybciej zakomentować i odkomentować :)
ison - jestem za cienki w programowaniu żeby zrozumieć co napisałeś :) Tak w ogóle to jest obowiązek pisania destruktora? bo przecież jest chyba coś takiego jak destruktor domyślny który zostanie utworzony automatycznie przez kompilator. |
|
ison |
» 2012-11-13 23:00:11 Tak w ogóle to jest obowiązek pisania destruktora? bo przecież jest chyba coś takiego jak destruktor domyślny który zostanie utworzony automatycznie przez kompilator.
|
Destruktor domyślny zajmuje się wszystkim prócz dealokowaniem pamięci przydzielonej dynamicznie. Aczkolwiek jeśli tej macierzy nie będziesz tworzył n razy w programie tylko stałą ilość to możesz olać usuwanie pamięci dynamicznej, i tak system sam się tym zajmie po zakończeniu aplikacji. Chodzi o to, że double ** tab_m; to jakiś konkretny 1 wskaźnik, jeśli skopiujesz cały obiekt, tzn zrobisz Macierz a; Macierz b = a; to nie przekopiujesz całej macierzy tab_m tylko sam wskaźnik, który będzie wskazywał na to samo. |
|
tygryseks Temat założony przez niniejszego użytkownika |
» 2012-11-13 23:13:56 Czyli problem jest w deklaracji macierzy? Próbowałem na różne sposoby i nie wiem jak zrobić żeby to działało poza usunięciem destruktora. |
|
crash |
» 2012-11-14 00:06:37 Teraz bangla: #include <iostream> #include <stdio.h> #include <cstdlib> #include <string.h>
using namespace std;
class Macierz { private: int m_size; double ** tab_m; public: Macierz( int = 2 ); ~Macierz(); void wypelnij_macierz(); void wypisz_macierz(); Macierz dodaj_macierz( Macierz & m2 ); Macierz & operator =( const Macierz & ); };
Macierz & Macierz::operator =( const Macierz & M ) { this->m_size = M.m_size; for( int i = 0; i < m_size; ++i ) for( int j = 0; j < m_size; ++j ) this->tab_m[ i ][ j ] = M.tab_m[ i ][ j ]; }
Macierz::Macierz( int size ) { m_size = size; tab_m = new double *[ m_size ]; for( int i = 0; i < m_size; i++ ) tab_m[ i ] = new double[ size ]; }
Macierz::~Macierz() { for( int i = 0; i < m_size; i++ ) delete tab_m[ i ]; delete[] tab_m; }
void Macierz::wypelnij_macierz() { for( int i = 0; i < m_size; i++ ) { for( int j = 0; j < m_size; j++ ) { cout << "Wprowadz wartosc do macierzy [ " << i << " ][ " << j << " ] : "; cin >> tab_m[ i ][ j ]; } } }
void Macierz::wypisz_macierz() { for( int i = 0; i < m_size; i++ ) { for( int j = 0; j < m_size; j++ ) { cout << tab_m[ i ][ j ] << " "; } cout << endl; } }
Macierz Macierz::dodaj_macierz( Macierz & m2 ) { cout << "Dodaje macierze \n"; cout << "Wynik dodawania: \n"; Macierz suma = * this; for( int i = 0; i < m_size; i++ ) { for( int j = 0; j < m_size; j++ ) { suma.tab_m[ i ][ j ] = tab_m[ i ][ j ] + m2.tab_m[ i ][ j ]; } } return suma; }
int main() { Macierz m1, m2, suma; m1.wypelnij_macierz(); cout << endl; m2.wypelnij_macierz(); cout << endl; cout << "Podane dane: \n\n"; m1.wypisz_macierz(); cout << endl; m2.wypisz_macierz(); cout << endl; suma = m1.dodaj_macierz( m2 ); cout << endl; suma.wypisz_macierz(); cout << endl; system( "PAUSE" ); return 0; }
Dzieki takiemu zabiegowi: class Macierz {... Macierz & operator =( const Macierz & );
Możliwy jest zabieg: Macierz X; ... Macierz Y = X; Zmieniłbym dodawanie na: Macierz Macierz::dodaj_macierz( Macierz & m2 ) { cout << "Dodaje macierze \n"; cout << "Wynik dodawania: \n"; for( int i = 0; i < m_size; i++ ) { for( int j = 0; j < m_size; j++ ) { this->tab_m[ i ][ j ] += m2.tab_m[ i ][ j ]; } } return * this; }
A najchętniej dodałbym przeładowane operatory +-*/ na szczęście w C++ można. Oddziel operacje na macierzach od wyświetlania wyników, tzn wyświetlenia wyników osobnych miejscach w kodzie |
|
« 1 » 2 |