CTRL85 Temat założony przez niniejszego użytkownika |
Destruktor klasy » 2017-05-19 23:28:06 piszę pewien programik na studi i mam problem jak powinien wyglądać destruktor. class WIELOMIAN { public: static int przeladowanych; int * tab; int degree; WIELOMIAN( int Degree,...) { degree = Degree; tab = new int[ Degree + 1 ]; Degree++; va_list arg; va_start( arg, Degree ); for( int i = 0; i < Degree; i++ ) tab[ i ] = va_arg( arg, int ); va_end( arg ); if( Degree > 1 ) DzielNWD( tab, Degree ); } WIELOMIAN() { tab = new int[ 1 ]; degree = 0; tab[ 0 ] = 0; }; WIELOMIAN( int tab[], int size, int gowno ) { degree = size; this->tab = new int[ degree + 1 ]; for( int i = 0; i < degree + 1; i++ ) this->tab[ i ] = tab[ i ]; DzielNWD( this->tab, this->degree + 1 ); } ~WIELOMIAN() { } } jak w destruktorze dałem delete tab; to program się wywala, prosiłbym o pomoc, jak poprawnie to zrobić. |
|
latajacaryba |
» 2017-05-20 13:41:58 jak w destruktorze dałem delete tab; to program się wywala |
Jesteś pewny, że nie próbujesz usunąć obiektu dwukrotnie? Przy delte konstruktor wywołuje się samodzielnie: #include <iostream>
class A { public: int x; ~A() { std::cout << "destruktor" << std::endl; } A( int y ) { x = y; } };
int main() { A * obj; obj = new A( 3 ); delete obj; std::cout << "obiekt zostal usuniety (delete)\n"; }
|
|
CTRL85 Temat założony przez niniejszego użytkownika |
» 2017-05-20 14:17:57 Visual pokazuje mi wycieki pamięci na przykład przy takim czymś: int main() { WIELOMIAN r( 2, 1, 2, 4 ); WIELOMIAN s( 3, 6, 5, 4, 2 ); } I w zadaniu jest napisane, że potrzebny jest odpowiedni destruktor do konstruktora o zmiennej liczbie parametrów. |
|
karambaHZP |
» 2017-05-20 15:46:12 |
|
CTRL85 Temat założony przez niniejszego użytkownika |
» 2017-05-20 19:07:59 Ja to rozumiem, tylko czemu przy takich konstruktorach, jak podałem jak destruktor wygląda: ~WIELOMIAN { delete[] tab; } To program się sypie? |
|
RazzorFlame |
» 2017-05-20 19:56:28 Edit: W którym miejscu dokładnie Ci się wywala? Crash może nastąpić w tym przypadku: - gdy spróbujesz odczytać później już usunięty z pamięci obiekt - gdy spróbujesz usunąć już usunięty obiekt Pokaż reszte kodu, przynajmniej te ważniejsze części. |
|
CTRL85 Temat założony przez niniejszego użytkownika |
» 2017-05-21 14:06:49 #include <iostream> #include <cstdarg> using namespace std;
class WIELOMIAN { public: static int przeladowanych; int * tab; int degree; WIELOMIAN( int Degree,...) { degree = Degree; tab = new int[ Degree + 1 ]; Degree++; va_list arg; va_start( arg, Degree ); for( int i = 0; i < Degree; i++ ) tab[ i ] = va_arg( arg, int ); va_end( arg ); if( Degree > 1 ) DzielNWD( tab, Degree ); } WIELOMIAN() { tab = new int[ 1 ]; degree = 0; tab[ 0 ] = 0; }; WIELOMIAN( int tab[], int size, int gowno ) { degree = size; this->tab = new int[ degree + 1 ]; for( int i = 0; i < degree + 1; i++ ) this->tab[ i ] = tab[ i ]; DzielNWD( this->tab, this->degree + 1 ); } ~WIELOMIAN() { delete[] tab; } void DelZero() { int i = this->degree; while( i >= 0 && this->tab[ i ] == 0 ) { if( this->degree >= 1 ) this->degree--; i--; } } void DelZero( WIELOMIAN & w1 ) { int i = w1.degree; while( i >= 0 && w1.tab[ i ] == 0 ) { if( w1.degree >= 1 ) w1.degree--; i--; } } int NWD( int tab[], int size ) { int * ModTab = new int[ size ]; int max = - 1000000000; for( int i = 0; i < size; i++ ) { if( tab[ i ] >= 0 ) ModTab[ i ] = tab[ i ]; else ModTab[ i ] = tab[ i ] *( - 1 ); if( ModTab[ i ] > max ) max = ModTab[ i ]; } int nwd = max; for( int l = size - 1; l > 0; l-- ) { int a = ModTab[ l ]; int b = ModTab[ l - 1 ]; int c = 0; while( b != 0 ) { c = a % b; a = b; b = c; } if( a <= nwd && a != 0 ) nwd = a; } delete ModTab; return nwd; } void DzielNWD( int tab[], int size ) { int nwd = NWD( tab, size ); if( nwd > 1 ) { for( int i = 0; i < size; i++ ) tab[ i ] = tab[ i ] / nwd; } } WIELOMIAN operator +( WIELOMIAN w1 ) { int n = 0; if( w1.degree > this->degree ) n = w1.degree; else n = this->degree; WIELOMIAN res; delete[] res.tab; res.tab = new int[ n + 1 ]; res.degree = n; for( int i = 0; i < n + 1; i++ ) { res.tab[ i ] = 0; if( i <= this->degree ) res.tab[ i ] += this->tab[ i ]; if( i <= w1.degree ) res.tab[ i ] += w1.tab[ i ]; } DelZero( res ); DzielNWD( res.tab, res.degree + 1 ); return res; } WIELOMIAN operator -( WIELOMIAN w1 ) { int n = 0; if( w1.degree > this->degree ) n = w1.degree; else n = this->degree; WIELOMIAN res; delete[] res.tab; res.degree = n; res.tab = new int[ n + 1 ]; for( int i = 0; i < n + 1; i++ ) { if( i <= this->degree ) res.tab[ i ] = this->tab[ i ]; else res.tab[ i ] = 0; if( i <= w1.degree ) res.tab[ i ] -= w1.tab[ i ]; } DelZero( res ); DzielNWD( res.tab, res.degree + 1 ); return res; } WIELOMIAN operator -() { WIELOMIAN res( this->tab, this->degree, 666 ); for( int i = 0; i < degree + 1; i++ ) res.tab[ i ] = - this->tab[ i ]; return res; } WIELOMIAN & operator =( WIELOMIAN w1 ) { this->degree = w1.degree; delete[] this->tab; this->tab = new int[ w1.degree + 1 ]; for( int i = 0; i < this->degree + 1; i++ ) this->tab[ i ] = w1.tab[ i ]; DelZero(); DzielNWD( this->tab, this->degree + 1 ); return * this; } WIELOMIAN operator *( WIELOMIAN w1 ) { WIELOMIAN * res = new WIELOMIAN(); res->degree = this->degree + w1.degree; res->tab = new int[ res->degree + 1 ]; for( int i = 0; i < res->degree + 1; i++ ) res->tab[ i ] = 0; for( int i = this->degree; i >= 0; i-- ) { for( int j = w1.degree; j >= 0; j-- ) { res->tab[ j + i ] +=( w1.tab[ j ] * this->tab[ i ] ); } } DelZero( * res ); DzielNWD( res->tab, res->degree + 1 ); return * res; } WIELOMIAN operator /( WIELOMIAN w1 ) { if( w1.degree > degree ) { WIELOMIAN res( 0, 0 ); return res; } else { int ** WielJeden = new int *[ degree + 1 ]; int ** WielDwa = new int *[ w1.degree + 1 ]; int ** wynik = new int *[ degree + 1 ]; int ** reszta = new int *[ degree + 1 ]; int StJeden = degree; int StDwa = w1.degree; for( int i = 0; i < StJeden + 1; i++ ) { WielJeden[ i ] = new int[ 2 ]; WielJeden[ i ][ 0 ] = tab[ i ]; WielJeden[ i ][ 1 ] = 1; } for( int i = 0; i < StDwa + 1; i++ ) { WielDwa[ i ] = new int[ 2 ]; WielDwa[ i ][ 0 ] = w1.tab[ i ]; WielDwa[ i ][ 1 ] = 1; } for( int i = 0; i < StJeden + 1; i++ ) { wynik[ i ] = new int[ 2 ]; reszta[ i ] = new int[ 2 ]; reszta[ i ][ 0 ] = 0; reszta[ i ][ 1 ] = 1; wynik[ i ][ 0 ] = 0; wynik[ i ][ 1 ] = 1; } while( StJeden >= StDwa ) { if( WielJeden[ StJeden ][ 0 ] % WielDwa[ StDwa ][ 0 ] == 0 ) { wynik[ StJeden - StDwa ][ 0 ] = WielJeden[ StJeden ][ 0 ] / WielDwa[ StDwa ][ 0 ]; cout << "WYNIK: "; for( int j = 0; j < StJeden + 1; j++ ) cout << wynik[ j ][ 0 ] << " "; for( int j = StDwa; j >= 0; j-- ) reszta[ j + StJeden - StDwa ][ 0 ] = wynik[ StJeden - StDwa ][ 0 ] * WielDwa[ j ][ 0 ] *( - 1 ); cout << "RESZTA: "; for( int j = 0; j < StJeden + 1; j++ ) cout << reszta[ j ][ 0 ] << " "; for( int j = 0; j < StJeden + 1; j++ ) reszta[ j ][ 0 ] += WielJeden[ j ][ 0 ]; for( int j = 0; j < StJeden + 1; j++ ) WielJeden[ j ][ 0 ] = reszta[ j ][ 0 ]; cout << "WIELOMIAN: "; for( int j = 0; j < StJeden + 1; j++ ) cout << WielJeden[ j ][ 0 ] << " "; cout << "\n"; for( int j = 0; j < StJeden + 1; j++ ) reszta[ j ][ 0 ] = 0; if( WielJeden[ StJeden ][ 0 ] == 0 ) StJeden--; } } int il = 1; for( int i = 0; i < degree - w1.degree + 1; i++ ) il *= wynik[ i ][ 1 ]; int * x = new int[ degree - w1.degree + 1 ]; for( int i = 0; i < degree - w1.degree + 1; i++ ) x[ i ] = wynik[ i ][ 0 ] * il; NWD( x, degree - w1.degree + 2 ); WIELOMIAN res( x, degree - w1.degree, 666 ); return res; } } WIELOMIAN operator %( WIELOMIAN w1 ) { return * this; } WIELOMIAN & operator +=( WIELOMIAN w1 ) { int n = 0; if( w1.degree > this->degree ) n = w1.degree; else n = this->degree; WIELOMIAN * res = new WIELOMIAN(); delete res->tab; res->tab = new int[ n + 1 ]; res->degree = n; for( int i = 0; i < n + 1; i++ ) { res->tab[ i ] = 0; if( i <= this->degree ) res->tab[ i ] += this->tab[ i ]; if( i <= w1.degree ) res->tab[ i ] += w1.tab[ i ]; } DelZero( * res ); DzielNWD( res->tab, res->degree + 1 ); * this = * res; delete res; return * this; } WIELOMIAN & operator -=( WIELOMIAN w1 ) { int n = 0; if( w1.degree > this->degree ) n = w1.degree; else n = this->degree; WIELOMIAN * res = new WIELOMIAN(); delete[] res->tab; res->degree = n; res->tab = new int[ n + 1 ]; for( int i = 0; i < n + 1; i++ ) { if( i <= this->degree ) res->tab[ i ] = this->tab[ i ]; else res->tab[ i ] = 0; if( i <= w1.degree ) res->tab[ i ] -= w1.tab[ i ]; } DelZero( * res ); DzielNWD( res->tab, res->degree + 1 ); * this = * res; delete res; return * this; } WIELOMIAN & operator *=( WIELOMIAN w1 ) { WIELOMIAN * res = new WIELOMIAN(); res->degree = this->degree + w1.degree; res->tab = new int[ res->degree + 1 ]; for( int i = 0; i < res->degree + 1; i++ ) res->tab[ i ] = 0; for( int i = this->degree; i >= 0; i-- ) { for( int j = w1.degree; j >= 0; j-- ) { res->tab[ j + i ] +=( w1.tab[ j ] * this->tab[ i ] ); } } DelZero( * res ); DzielNWD( res->tab, res->degree + 1 ); * this = * res; delete res; return * this; } WIELOMIAN & operator /=( WIELOMIAN w1 ) { return * this; } WIELOMIAN & operator %=( WIELOMIAN w1 ) { return * this; } WIELOMIAN operator <<( int n ) { if( n < 0 ) { WIELOMIAN res( 0, 0 ); return res; } WIELOMIAN res( tab, degree, 666 ); WIELOMIAN s( 1, 0, 1 ); for( int i = 0; i < n; i++ ) { res = res * s; DzielNWD( res.tab, res.degree + 1 ); } return res; } WIELOMIAN operator >>( int n ) { WIELOMIAN res = WIELOMIAN( tab, degree, 666 ); if( n == this->degree ) { res.tab[ 0 ] = tab[ degree ]; res.degree = 0; } else if( n > this->degree || n < 0 ) { res.degree = 0; res.tab[ 0 ] = 0; } else if( n < this->degree && n > 0 ) { for( int j = 0; j < n; j++ ) { res.degree--; for( int j = 0; j <= degree; j++ ) res.tab[ j ] = res.tab[ j + 1 ]; } } DelZero( res ); DzielNWD( res.tab, res.degree + 1 ); return res; } WIELOMIAN & operator <<=( int n ) { if( n < 0 ) { WIELOMIAN res( 0, 0 ); return res; } WIELOMIAN res( tab, degree, 666 ); WIELOMIAN s( 1, 0, 1 ); for( int i = 0; i < n; i++ ) { res = res * s; DzielNWD( res.tab, res.degree + 1 ); } * this = res; return * this; } WIELOMIAN & operator >>=( int n ) { WIELOMIAN res = WIELOMIAN( tab, degree, 666 ); if( n == this->degree ) { res.tab[ 0 ] = tab[ degree ]; res.degree = 0; } else if( n > this->degree || n < 0 ) { res.degree = 0; res.tab[ 0 ] = 0; } else if( n < this->degree && n > 0 ) { for( int j = 0; j < n; j++ ) { res.degree--; for( int j = 0; j <= degree; j++ ) res.tab[ j ] = res.tab[ j + 1 ]; } } DelZero( res ); DzielNWD( res.tab, res.degree + 1 ); * this = res; return * this; } WIELOMIAN & operator ++() { for( int i = 0; i < this->degree + 1; i++ ) this->tab[ i ] = this->tab[ i ] + 1; DelZero(); if( this->degree > 0 ) DzielNWD( this->tab, this->degree + 1 ); return * this; } WIELOMIAN operator ++( int ) { WIELOMIAN res = WIELOMIAN( this->tab, this->degree, 666 ); ++* this; DelZero( res ); DelZero(); if( this->degree > 0 ) DzielNWD( this->tab, this->degree + 1 ); return res; } WIELOMIAN & operator --() { for( int i = 0; i < this->degree + 1; i++ ) this->tab[ i ] = this->tab[ i ] - 1; DelZero(); if( this->degree > 0 ) DzielNWD( this->tab, this->degree + 1 ); return * this; } WIELOMIAN operator --( int ) { WIELOMIAN res = WIELOMIAN( this->tab, this->degree, 666 ); --* this; DelZero( res ); DelZero(); if( this->degree > 0 ) DzielNWD( this->tab, this->degree + 1 ); return res; } void * operator new( size_t size ) { przeladowanych++; return::operator new( size ); } void operator delete( void * wsk ) { przeladowanych--; ::operator delete( wsk ); } };
istream & operator >>( istream & s, WIELOMIAN & w ) { s >> w.degree; w.tab = new int[ w.degree + 1 ]; for( int i = 0; i < w.degree + 1; i++ ) s >> w.tab[ i ]; w.DzielNWD( w.tab, w.degree + 1 ); return s; } ostream & operator <<( ostream & s, WIELOMIAN w ) { s << "( "; w.DzielNWD( w.tab, w.degree + 1 ); for( int i = 0; i < w.degree; i++ ) s << w.tab[ i ] << ", "; s << w.tab[ w.degree ] << " )"; return s; }
bool operator <( const WIELOMIAN w1, const WIELOMIAN w2 ) { if( w1.degree < w2.degree ) return true; else if( w1.degree > w2.degree ) return false; if( w1.degree == w2.degree ) { for( int i = w1.degree; i >= 0; i-- ) if( w1.tab[ i ] < w2.tab[ i ] ) return true; } return false; } bool operator <=( const WIELOMIAN w1, const WIELOMIAN w2 ) { if( w1.degree < w2.degree ) return true; else if( w1.degree > w2.degree ) return false; if( w1.degree == w2.degree ) { for( int i = w1.degree; i >= 0; i-- ) if( w1.tab[ i ] > w2.tab[ i ] ) return false; } return true; } bool operator >( const WIELOMIAN w1, const WIELOMIAN w2 ) { if( w1.degree > w2.degree ) return true; else if( w1.degree < w2.degree ) return false; if( w1.degree == w2.degree ) { for( int i = w1.degree; i >= 0; i-- ) if( w1.tab[ i ] > w2.tab[ i ] ) return true; } return false; } bool operator >=( const WIELOMIAN w1, const WIELOMIAN w2 ) { if( w1.degree > w2.degree ) return true; else if( w1.degree < w2.degree ) return false; if( w1.degree == w2.degree ) { for( int i = w1.degree; i >= 0; i-- ) if( w1.tab[ i ] < w2.tab[ i ] ) return false; } return true; } bool operator ==( const WIELOMIAN w1, const WIELOMIAN w2 ) { if( w1.degree != w2.degree ) return false; if( w1.degree == w2.degree ) { for( int i = w1.degree; i >= 0; i-- ) if( w1.tab[ i ] != w2.tab[ i ] ) return false; } return true; } bool operator !=( const WIELOMIAN w1, const WIELOMIAN w2 ) { if( w1.degree != w2.degree ) return true; if( w1.degree == w2.degree ) { for( int i = w1.degree; i >= 0; i-- ) if( w1.tab[ i ] != w2.tab[ i ] ) return true; } return false; } Cały kod, krzaczy się na przykład przy int main() { WIELOMIAN r( 2, 1, 2, 4 ); WIELOMIAN s( 3, 6, 5, 4, 2 ); cout << r << endl; } |
|
michal11 |
» 2017-05-21 14:39:59 Ok, masz crasha ponieważ źle napisałeś operator<<, u ciebie wygląda to tak ostream & operator <<( ostream & s, WIELOMIAN w ) czyli wchodzą do tej funkcji robisz kopię obiektu który przekazujesz, ponieważ nie napisałeś poprawnego konstruktora kopiującego więc kompilator sam go wygenerował, ale w twoim wypadku jest robione płytkie kopiowanie (kopiowany jest tylko adres tablicy), więc kody wychodzisz z tej funkcji to obiekty tymczasowe są kopiowane, takim obiektem jest w, wywoływany jest jego destruktor który kasuje tablicę, ale ponieważ to była kopia więc obiekt z maina trzyma adres który już został usunięty więc kiedy jest wywoływany jego konstruktor (przy wychodzeniu z main) program wywala się ponieważ próbuje drugi raz zwolnić pamięć już wcześniej zwolnioną, więc przede wszystkim argumenty przekazuj przez referencję a nie przez kopiowanie oraz dopisz poprawny konstruktor kopiujący i powinno być ok. |
|
« 1 » 2 |