c++ - problem z destruktorem
Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?
Zarejestruj się!

c++ - problem z destruktorem

AutorWiadomość
Temat założony przez niniejszego użytkownika
c++ - problem z destruktorem
» 2017-10-08 21:43:33
Witam. Piszę program o działaniach na macierzach 2x2 , i bez destruktora wszystko działa dobrze , lecz jak destruktor wchodzi do gry to wywala błąd .

Log wyjątku (w linijce 88 pliku matrix.cpp)

Zgłoszono wyjątek w lokalizacji 0x000727E8 w Projekt1.exe: 0xC0000005: Naruszenie zasad dostępu podczas odczytywania w lokalizacji 0xDDDDDDDD.: wystąpił wyjątek

Wstawiam również zrzut :

https://gyazo.com/479746a376819b1ed5a19bdbfc37b272


cały program jest w 3 plikach

matrix.cpp ( rozpisanie klas)


C/C++
#include<iostream>
#include"Header.h"
using namespace std;


Matrix::Matrix()
{
   
    wiel_x = 2;
    wiel_y = 2;
    tablica = new double *[ wiel_x ]; //tworzenie macierzy dynamicznie
    for( int i = 0; i < wiel_y; i++ )
    {
        tablica[ i ] = new double[ wiel_y ];
    }
   
   
   
    for( int t = 0; t < wiel_y; t++ )
    {
        for( int k = 0; k < wiel_x; k++ )
        {
            tablica[ t ][ k ] = 0;
        }
    }
   
   
   
}


Matrix Matrix::operator +=( const Matrix & m2 )
{
    for( int w = 0; w < wiel_x; w++ )
    {
        for( int k = 0; k < wiel_y; k++ )
        {
            tablica[ w ][ k ] += m2.tablica[ w ][ k ];
        }
    }
   
   
   
    return * this;
}

//Matrix Matrix::operator*=(const Matrix & m2)
//{

// tablica[0][0] = (tablica[0][0] * m2.tablica[0][0]) + (tablica[0][1] * m2.tablica[1][0]);
// tablica[0][1] = (tablica[0][0] * m2.tablica[0][1]) + (tablica[0][1] * m2.tablica[1][1]);
//tablica[1][0] = (tablica[1][0] * m2.tablica[0][0]) + (tablica[1][1] * m2.tablica[1][0]);
// tablica[1][1] = (tablica[1][0] * m2.tablica[0][1]) + (tablica[1][1] * m2.tablica[1][1]);


// return*this;
//}





Matrix::~Matrix() //kasowanie macierzy dynamicznie
{
    for( int i = 0; i < wiel_y; i++ )
         delete tablica[ i ];
   
    delete tablica;
   
   
}

void Matrix::ustaw( int x, int y, double wartosc )
{
    tablica[ x ][ y ] = wartosc;
}

void Matrix::wyswietl()
{
   
    cout << "Twoja macierz to" << endl;
   
    for( int a = 0; a < wiel_x; a++ )
    {
        cout << endl;
       
        for( int b = 0; b < wiel_y; b++ )
        {
            cout << tablica[ a ][ b ] << " ";
        }
    }
}

plik nagłowkowy
C/C++
#pragma once

class Matrix {
protected:
    int wiel_x; // wiersze
    int wiel_y; // kolumny
   
    double ** tablica;
public:
    Matrix();
    //Matrix(const Matrix&m2);//konstruktor kopiujacy
    Matrix operator +=( const Matrix & m2 );
    //Matrix operator*=(const Matrix&m2);
    ~Matrix();
    //ustawianie wartsoci w danym miejscu macierzy
    void ustaw( int x, int y, double wartosc );
   
    void wyswietl();
   
   
};

plik main.cpp

C/C++
#include "Header.h"
#include<cstdlib>
#include<iostream>
using namespace std;
int main()
{
   
    Matrix a;
    Matrix b;
    a.ustaw( 0, 0, 1.0 );
    a.ustaw( 0, 1, 2.0 );
    a.ustaw( 1, 0, 3.0 );
    a.ustaw( 1, 1, 4.0 );
    a.wyswietl();
   
    cout << endl;
    cout << endl;
    b.ustaw( 0, 0, 4.0 );
    b.ustaw( 0, 1, 2.0 );
    b.ustaw( 1, 0, 3.0 );
    b.ustaw( 1, 1, 4.0 );
    b.wyswietl();
   
    a += b;
   
    a.wyswietl();
   
    system( "pause" );
   
}


P-165547
» 2017-10-08 21:54:31
C/C++
Matrix Matrix::operator +=( const Matrix & m2 );
Brakuje referencji przy zwracanej wartości.
P-165548
Temat założony przez niniejszego użytkownika
» 2017-10-08 22:00:55
C/C++
return * this;
}
 
w sensie że tutaj?
P-165549
» 2017-10-08 22:04:19
C/C++
Matrix & Matrix::operator +=( const Matrix & m2 );
W sensie, że tutaj.
P-165551
Temat założony przez niniejszego użytkownika
» 2017-10-08 22:06:20
Ok super , dziękuje a dlaczego akurat tak trzeba to zrobić ? Jaki jest tego powód tak naprawde?
P-165552
» 2017-10-08 22:15:42
Zwracając obiekt przez wartość wykonujesz tzw. płytką kopię obiektu (nie określiłeś konstruktora kopiującego, więc kompilator zrobił to za ciebie), która zawiera kopię wskaźnika
double ** tablica
. Czas życia obiektu zwracanego kończy się wraz z tą linijką:
C/C++
a += b; // w tym miejscu jest wywoływany destruktor, który zwalnia pamięć tablicy

Przez to później destruktor obiektu
a
 próbuje zwolnić już zwolnioną pamięć.
P-165553
Temat założony przez niniejszego użytkownika
» 2017-10-08 22:19:05
Rozumiem , dziękuje. Można zamknąć.
P-165554
Temat założony przez niniejszego użytkownika
» 2017-10-10 18:20:26
Ok może jeszcze nie , mam dwa pytania jeszcze jednak.
matrix.cpp
C/C++
#include<iostream>
#include"Header.h"
using namespace std;


Matrix::Matrix()
{
   
    wiel_x = 2;
    wiel_y = 2;
    tablica = new double *[ wiel_x ]; //tworzenie macierzy dynamicznie
    for( int i = 0; i < wiel_y; i++ )
    {
        tablica[ i ] = new double[ wiel_y ];
    }
   
   
   
    for( int t = 0; t < wiel_y; t++ )
    {
        for( int k = 0; k < wiel_x; k++ )
        {
            tablica[ t ][ k ] = 0;
        }
    }
   
   
   
}

Matrix::Matrix( const Matrix & m2 )
{
   
   
    tablica = new double *[ wiel_x ]; //tworzenie macierzy dynamicznie
    for( int i = 0; i < wiel_y; i++ )
    {
        m2.tablica[ i ] = new double[ wiel_y ];
    }
   
   
   
    for( int t = 0; t < wiel_y; t++ )
    {
        for( int k = 0; k < wiel_x; k++ )
        {
            m2.tablica[ t ][ k ] = 0;
        }
    }
   
}


Matrix & Matrix::operator +=( const Matrix & m2 )
{
    for( int w = 0; w < wiel_x; w++ )
    {
        for( int k = 0; k < wiel_y; k++ )
        {
            tablica[ w ][ k ] += m2.tablica[ w ][ k ];
        }
    }
   
   
   
    return * this;
}

Matrix & Matrix::operator *( const Matrix & m2 )
{
    return( * this *= m2 );
}

Matrix & Matrix::operator +( const Matrix & m2 )
{
    return( * this += m2 );
}

Matrix & Matrix::operator *=( const Matrix & m2 )
{
    double tab1, tab2, tab3, tab4;
    tab1 = tablica[ 0 ][ 0 ] * m2.tablica[ 0 ][ 0 ] + tablica[ 0 ][ 1 ] * m2.tablica[ 1 ][ 0 ];
    tab2 = tablica[ 0 ][ 0 ] * m2.tablica[ 0 ][ 1 ] + tablica[ 0 ][ 1 ] * m2.tablica[ 1 ][ 1 ];
    tab3 = tablica[ 1 ][ 0 ] * m2.tablica[ 0 ][ 0 ] + tablica[ 1 ][ 1 ] * m2.tablica[ 1 ][ 0 ];
    tab4 = tablica[ 1 ][ 0 ] * m2.tablica[ 0 ][ 1 ] + tablica[ 1 ][ 1 ] * m2.tablica[ 1 ][ 1 ];
    tablica[ 0 ][ 0 ] = tab1;
    tablica[ 0 ][ 1 ] = tab2;
    tablica[ 1 ][ 0 ] = tab3;
    tablica[ 1 ][ 1 ] = tab4;
   
   
    return * this;
}

bool Matrix::operator ==( const Matrix & m2 )
{
    for( int i = 0; i < wiel_x; i++ )
    {
        for( int j = 0; i < wiel_y; j++ )
        {
            if( tablica[ i ][ j ] == m2.tablica[ i ][ j ] )
                 return true;
            else
            {
                return false;
                cout << "macierze nie są równe" << endl;
                break;
            }
           
        }
    }
    if( true )
         cout << "macierze są równe" << endl;
   
}








Matrix & Matrix::operator =( const Matrix & m2 )
{
   
    tablica[ 0 ][ 0 ] = m2.tablica[ 0 ][ 0 ];
    tablica[ 0 ][ 1 ] = m2.tablica[ 0 ][ 1 ];
    tablica[ 1 ][ 0 ] = m2.tablica[ 1 ][ 0 ];
    tablica[ 1 ][ 1 ] = m2.tablica[ 1 ][ 1 ];
    return * this;
}

double Matrix::wyznacznik()
{
    return tablica[ 0 ][ 0 ] * tablica[ 1 ][ 1 ] - tablica[ 0 ][ 1 ] * tablica[ 1 ][ 0 ];
}

Matrix & Matrix::operator -=( const Matrix & m2 )
{
    for( int w = 0; w < wiel_x; w++ )
    {
        for( int k = 0; k < wiel_y; k++ )
        {
            tablica[ w ][ k ] -= m2.tablica[ w ][ k ];
        }
    }
    return * this;
}

Matrix & Matrix::operator -( const Matrix & m2 )
{
    return( * this -= m2 );
}


Matrix::~Matrix() //kasowanie macierzy dynamicznie
{
    for( int i = 0; i < wiel_y; i++ )
         delete tablica[ i ];
   
    delete tablica;
   
   
}

void Matrix::ustaw( int x, int y, double wartosc )
{
    tablica[ x ][ y ] = wartosc;
}

void Matrix::wyswietl()
{
   
    cout << "Twoja macierz to" << endl;
   
    for( int a = 0; a < wiel_x; a++ )
    {
        cout << endl;
       
        for( int b = 0; b < wiel_y; b++ )
        {
            cout << tablica[ a ][ b ] << " ";
        }
    }
}

header.h
C/C++
#pragma once

class Matrix {
protected:
    int wiel_x; // wiersze
    int wiel_y; // kolumny
   
    double ** tablica;
public:
    Matrix();
    Matrix( const Matrix & m2 ); //konstruktor kopiujacy
    Matrix & operator +=( const Matrix & m2 );
    Matrix & operator *( const Matrix & m2 );
    Matrix & operator +( const Matrix & m2 );
    Matrix & operator *=( const Matrix & m2 );
    bool operator ==( const Matrix & m2 );
    Matrix & operator =( const Matrix & m2 );
    double wyznacznik();
    Matrix & operator -=( const Matrix & m2 );
    Matrix & operator -( const Matrix & m2 );
    ~Matrix();
    //ustawianie wartsoci w danym miejscu macierzy
    void ustaw( int x, int y, double wartosc );
   
    void wyswietl();
   
   
};

main.cpp
C/C++
#include "Header.h"
#include<cstdlib>
#include<iostream>
using namespace std;
int main()
{
   
    Matrix a;
    Matrix b;
    a.ustaw( 0, 0, 8.0 );
    a.ustaw( 0, 1, 2.0 );
    a.ustaw( 1, 0, 1.0 );
    a.ustaw( 1, 1, 4.0 );
    a.wyswietl();
   
    b.wyswietl();
    b = a;
   
    b.wyswietl();
   
   
    system( "pause" );
   
}

Chodzi mi o konstruktor kopiujący , czy jest on dobrze skonstrukowany? Mamy wymagany ten konstruktor , i chciałbym się upewnić czy dobrze wygląda czyu coś trzeba zmienic?

Oraz metoda
C/C++
bool Matrix::operator ==( const Matrix & m2 )

chciałbym , aby wypisało mi po przyrównaniu dwóch macierzy czy są równe czy nie , coś muszę zmienić napewno , ponieważ tak nie działa.  Coś trzeba poprawić czy może jeszcze jakiś przeciążyć?

P-165610
« 1 » 2 3
 Strona 1 z 3Następna strona