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

[C++] Zawieszenie programu przy wywołaniu destruktora

Ostatnio zmodyfikowano 2012-11-28 21:42
Autor Wiadomość
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.


C/C++
#include <iostream>
#include <stdio.h>
#include <cstdlib>

using namespace std;

class Macierz
{
private:
    int m_size;
    double ** tab_m;
public:
   
    Macierz( int = 2 ); // konstruktor
    // ~Macierz(); // destruktor
   
    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 ];
   
}

//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;
   
    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()
{
    //Deklaracja obiektów klasy Macierz
    Macierz m1, m2, suma;
   
    // Pobranie danych do macierzy
    m1.wypelnij_macierz();
    cout << endl;
    m2.wypelnij_macierz();
    cout << endl;
   
    // Wyswietlenie podanych macierzy w celu sprawdzenia
    cout << "Podane dane: \n\n";
    m1.wypisz_macierz();
    cout << endl;
    m2.wypisz_macierz();
    cout << endl;
   
    // Dodawanie macierzy
    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
P-69197
akwes
» 2012-11-13 22:40:36
Kod umieszczaj w tagach [cpp] kod [/cpp]
P-69199
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.
P-69201
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
P-69202
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.
P-69203
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.
P-69204
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.
P-69206
crash
» 2012-11-14 00:06:37
Teraz bangla:

C/C++
#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 ); // konstruktor
    ~Macierz(); // destruktor
   
    void wypelnij_macierz();
    void wypisz_macierz();
   
    Macierz dodaj_macierz( Macierz & m2 );
   
    Macierz & operator =( const Macierz & ); //przeladowany operator =
   
};



Macierz & Macierz::operator =( const Macierz & M ) //tu jego implementacja
{
    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() //destruktor
{
    for( int i = 0; i < m_size; i++ )
         delete tab_m[ i ]; //usuwanie elementow wiersza
   
    delete[] tab_m; //usuwanie wiersza w kolumnie
}

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()
{
    //Deklaracja obiektów klasy Macierz
    Macierz m1, m2, suma;
   
    // Pobranie danych do macierzy
    m1.wypelnij_macierz();
    cout << endl;
    m2.wypelnij_macierz();
    cout << endl;
   
    // Wyswietlenie podanych macierzy w celu sprawdzenia
    cout << "Podane dane: \n\n";
    m1.wypisz_macierz();
    cout << endl;
    m2.wypisz_macierz();
    cout << endl;
   
    // Dodawanie macierzy
    suma = m1.dodaj_macierz( m2 );
    cout << endl;
    suma.wypisz_macierz();
    cout << endl;
   
   
    system( "PAUSE" );
    return 0;
}

Dzieki takiemu zabiegowi:

C/C++
class Macierz {...
    Macierz & operator =( const Macierz & );

Możliwy jest zabieg: Macierz X; ... Macierz Y = X;

Zmieniłbym dodawanie na:

C/C++
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++ )
        {
            this->tab_m[ i ][ j ] += /*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 
P-69207
« 1 » 2
  Strona 1 z 2 Następna strona