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

Metoda LU - wyciek pamięci

Ostatnio zmodyfikowano 2016-01-08 19:25
Autor Wiadomość
mattmaker
Temat założony przez niniejszego użytkownika
Metoda LU - wyciek pamięci
» 2016-01-08 11:43:45
Witam serdecznie,

od dwóch dni męczę się z (moim zdaniem) wyciekiem pamięci z jednej z funkcji, której zadaniem jest rozłożenie macierzy A na macierz LU (Rozkład metodą Doolittle'a). Program kompiluje się bez żadnych błędów, ale gdy dochodzi do tejże funkcji, wysypuje się. Nie potrafię stwierdzić w którym miejscu jest błąd.


Byłbym ogromnie wdzięczny za wszelkie wskazówki i rady.
Pozdrawiam serdecznie.

C/C++
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>


using namespace std;

// Funkcja wczytuje macierz A i wektor B z pliku i wrzuca je do tablicy dwuwymiarowej "tym" do dalszej obrobki

double czytaj( int rozmiar, int wektor_b, double ** tym )
{
    int i = 0;
    int j = 0;
   
    std::fstream plik;
    string temp;
    plik.open( "test.txt", std::ios::in | std::ios::out );
    if( plik.good() == false )
    {
        cout << "Nie mozna otworzyc pliku" << endl;
        return 0;
    }
   
    if( plik.good() == true )
    {
       
        for( j = 0; j < rozmiar; j++ )
        {
            for( i = 0; i < rozmiar; i++ ) plik >> tym[ j ][ i ];
           
        }
    }
    plik.close();
    plik.open( "test.txt", std::ios::in | std::ios::out );
    if( plik.good() == true )
    {
        j = 0;
        for( i = rozmiar; i < rozmiar + wektor_b; i++ ) plik >> tym[ i ][ j ];
       
    }
    plik.close();
   
   
    return ** tym;
   
}

// Dekompozycja LU metoda Doolittle'a

void lu( double ** macierzA, double ** macierzL, double ** macierzU, int rozmiar )
{
    int i, j, k;
   
    for( i = 0; i < rozmiar; i++ )
    for( j = 0; j < rozmiar; j++ )
    {
        if( j < i )
             macierzL[ j ][ i ] = 0;
       
        else
        {
            macierzL[ j ][ i ] = macierzA[ j ][ i ];
           
            for( k = 0; k < i; k++ )
            {
                macierzL[ j ][ i ] = macierzL[ j ][ i ] - macierzL[ j ][ k ] * macierzU[ k ][ i ];
            }
        }
    }
   
    for( j = 0; j < rozmiar; j++ )
    {
        if( j < i )
             macierzU[ i ][ j ] = 0;
       
        else if( j == 1 )
             macierzU[ i ][ j ] = 1;
        else
        {
            macierzU[ i ][ j ] = macierzA[ i ][ j ] / macierzL[ i ][ i ];
           
            for( k = 0; k < i; k++ )
            {
                macierzU[ i ][ j ] = macierzU[ i ][ j ] -(( macierzL[ i ][ k ] * macierzU[ k ][ j ] ) / macierzL[ i ][ i ] );
            }
           
        }
    }
   
}

int main()
{
    int rozmiar = 0;
    int wektor_b = 0;
    int wektor_x = 0;
    int i;
   
    cout << "Podaj rozmiar macierzy A = ";
    cin >> rozmiar;
    cout << "Podaj rozmiar wektora B = ";
    cin >> wektor_b;
    cout << "Podaj rozmiar wektora X = ";
    cin >> wektor_x;
   
    int abc = rozmiar + wektor_b;
    // Dynamiczna alokacja tymczasowej macierzy
   
    double ** tym = new double *[ abc ];
    for( i = 0; i < abc; i++ ) tym[ i ] = new double[ abc ];
   
    // Dynamiczna alokacja macierzy A
   
    double ** macierzA = new double *[ rozmiar ];
    for( i = 0; i < rozmiar; i++ ) macierzA[ i ] = new double[ rozmiar ];
   
    // Dynamiczna alokacja wektora B
   
    double * WektorB = new double[ wektor_b ];
   
    // dynamiczna alokacja macierzy l i u
    double ** macierzL = new double *[ rozmiar ];
    for( i = 0; i < rozmiar; i++ ) macierzL[ i ] = new double[ rozmiar ];
   
    double ** macierzU = new double *[ rozmiar ];
    for( i = 0; i < rozmiar; i++ ) macierzU[ i ] = new double[ rozmiar ];
   
   
   
    // Wczytanie danych z pliku i rozlozenie danych do poszczegolnych tablic zmiennych
   
    czytaj( rozmiar, wektor_b, tym );
   
    // Dekompozycja macierzy A na macierze LU metoda Doolittle'a
   
    lu( macierzA, macierzL, macierzU, rozmiar );
   
   
    // Petle wyswietlajace zawartosc macierzy
   
    /*
                for(int i = 0; i < abc; ++i)
                {
                    for(int j = 0; j < rozmiar; ++j)
                    {
                        cout << tym[i][j] << " ";
                    }
                    cout << endl;
                }
   
                for(i = 0; i < rozmiar; i++)
                {
                    for (j = 0; j < rozmiar; j++)
                    {
                        macierzA[i][j] = tym[i][j];
                        cout << macierzA[i][j] << " ";
                    }
                    cout << endl;
                }
   
        */
   
   
    // Zwolnienie pamieci
   
    for( i = 0; i < rozmiar; i++ ) delete[] macierzA[ i ];
   
    delete[] macierzA;
   
    delete[] WektorB;
   
    for( i = 0; i < rozmiar; i++ ) delete[] tym[ i ];
   
    delete[] tym;
   
    for( i = 0; i < rozmiar; i++ ) delete[] macierzL[ i ];
   
    delete[] macierzL;
   
    for( i = 0; i < rozmiar; i++ ) delete[] macierzU[ i ];
   
    delete[] macierzU;
   
   
    getchar();
    return 0;
}

Przykład zawartości pliku do odczytu:

1 4 7 /*
2 5 8     macierz A
3 6 9 */
1 \\
1    wektor B
1 \\


P-143115
darko202
» 2016-01-08 12:44:00
spróbuj zgodnie z
http://cpp0x.pl/artykuly/?id=4
wykryć co wycieka
P-143117
mateczek
» 2016-01-08 14:21:20
tym[] ma rozmiar większy niż zmienna "rozmiar"?? !!!

C/C++
for( i = rozmiar; i < rozmiar + wektor_b; i++ ) plik >> tym[ i ][ j ]; // a tu nie lecisz za rozmiar ??

for( i = 0; i < rozmiar; i++ ) delete[] tym[ i ];

delete[] tym;

A jak chcesz wykryć gdzie się program sypie polecam debuger!!!

w większości środowsik działa podobnie

https://www.youtube.com/watch​?v=L9JvSHYLvuw
P-143120
michal11
» 2016-01-08 17:25:58
Problemem nie jest wyciek pamięci tylko wychodzenie poza zakres tablicy.
W funkcji lu() dodaj
--i;
 po pierwszym, podwójnym for:

C/C++
void lu( double ** macierzA, double ** macierzL, double ** macierzU, int rozmiar )
{
    int i, j, k;
   
    for( i = 0; i < rozmiar; i++ )
    for( j = 0; j < rozmiar; j++ )
    {
        if( j < i )
             macierzL[ j ][ i ] = 0;
       
        else
        {
            macierzL[ j ][ i ] = macierzA[ j ][ i ];
           
            for( k = 0; k < i; k++ )
            {
                macierzL[ j ][ i ] = macierzL[ j ][ i ] - macierzL[ j ][ k ] * macierzU[ k ][ i ];
            }
        }
    }
   
    --i;
   
    for( j = 0; j < rozmiar; j++ )
    {
        if( j < i )
             macierzU[ i ][ j ] = 0;
       
        else if( j == 1 )
             macierzU[ i ][ j ] = 1;
        else
        {
            macierzU[ i ][ j ] = macierzA[ i ][ j ] / macierzL[ i ][ i ];
           
            for( k = 0; k < i; k++ )
            {
                macierzU[ i ][ j ] = macierzU[ i ][ j ] -(( macierzL[ i ][ k ] * macierzU[ k ][ j ] ) / macierzL[ i ][ i ] );
            }
           
        }
    }
   
}
P-143130
mattmaker
Temat założony przez niniejszego użytkownika
» 2016-01-08 19:25:29
Tak jest @michal11 !! Bardzo dziękuję Ci za zwrócenie na to uwagi. Teraz wszystko śmiga tak jak powinno.

@darko202 dzięki również !
@mateczek wszystko było w granicy rozmiaru, ale dzięki za zwrócenie uwagi na nie zwolnienie całej pamięci.

Spokojnego weekendu chłopaki. Dzięki jeszcze raz !
P-143135
« 1 »
  Strona 1 z 1