Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Destruktor klasy

Ostatnio zmodyfikowano 2017-05-21 21:23
Autor Wiadomość
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.

C/C++
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ć.
P-161319
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:
C/C++
#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";
   
}
P-161338
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ś:

C/C++
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.
P-161340
karambaHZP
» 2017-05-20 15:46:12
To co konstruktor przydziela operatorem
new
 destruktor musi zwolnić operatorem
delete
.
https://dsp.krzaq.cc/post/176​/ucze-sie-cxx-kiedy-uzywac-new-​i-delete​/
P-161342
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:
C/C++
~WIELOMIAN {
    delete[] tab;
}

To program się sypie?
P-161353
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.
P-161355
CTRL85
Temat założony przez niniejszego użytkownika
» 2017-05-21 14:06:49
C/C++
#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 ]; //ROZMIAR!?
            int ** reszta = new int *[ degree + 1 ]; //ROZMIAR!?
           
            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 < degree+1;i++)
            cout << WielJeden[i][0] << " ";*/
            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

C/C++
int main() {
    WIELOMIAN r( 2, 1, 2, 4 );
    WIELOMIAN s( 3, 6, 5, 4, 2 );
   
    cout << r << endl;
}
P-161376
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.
P-161377
« 1 » 2
  Strona 1 z 2 Następna strona