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

Jak zapobiec wyciekowi pamięci (memory leak)?

Ostatnio zmodyfikowano 2010-08-12 22:32
Autor Wiadomość
Dybusek
Temat założony przez niniejszego użytkownika
Jak zapobiec wyciekowi pamięci (memory leak)?
» 2010-08-12 20:57:20
Witam!
Mam w swoim programie wyciek pamięci i nie wiem jak poprawnie użyć destruktora żeby problem został rozwiązany. Próbowałem kilku opcji lecz bez powodzenia. Proszę o pomoc.
C/C++
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

class ksiazka
{
public:
    int id_ks, stan;
    string tytul, autor, numer_seryjny;
public:
    ksiazka( int new_id_ks, string new_autor, string new_tytul, string new_numer_seryjny, int new_stan )
    {
        id_ks = new_id_ks;
        autor = new_autor;
        tytul = new_tytul;
        numer_seryjny = new_numer_seryjny;
        stan = new_stan;
    } //konstruktor
    ksiazka() { } //konstruktor bez argumentow
    ~ksiazka() { } //destruktor
};

bool wczytywanie_ksiazka( ifstream & plik, vector < ksiazka > & ksiazka_t )
{
    int id_ks, stan;
    string autor, tytul, numer_seryjny;
    plik.open( "ksiazka.txt" );
    if( !plik.good() )
    {
        cout << "Brak dostepu do pliku 'ksiazka.txt'. Aby zakonczyc nacisnij ENTER";
        cin.sync();
        cin.get();
        plik.close();
        plik.clear();
        return 1;
    }
    else
    {
        while( !plik.eof() )
        {
            plik >> id_ks >> autor >> tytul >> numer_seryjny >> stan;
            ksiazka_t.push_back( ksiazka( id_ks, autor, tytul, numer_seryjny, stan ) );
        }
        plik.close();
        plik.clear();
        return 0;
    }
} // koniec wczytywanie_ksiazka

int main()
{
    ifstream plik;
    vector < ksiazka > ksiazka_t;
    if( wczytywanie_ksiazka( plik, ksiazka_t ) ) return 1;
   
    return 0;
}
P-20750
Elaine
» 2010-08-12 21:07:19
Nie ma żadnego wycieku pamięci.
P-20751
Dybusek
Temat założony przez niniejszego użytkownika
» 2010-08-12 21:29:33
Nie znam się dobrze na programowaniu obiektowym. Myślałem, że gdzieś tutaj błąd popełniłem.
Wrzucę cały kod: (Program piszę w ramach stypendium, nie w celach zarobkowych)
C/C++
/*****************************************************************************/
/*         Program "Biblioteka Szkolna 2010" by xxx 2010r         */
/*****************************************************************************/

#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
#include <windows.h>
#include <cstdlib>

using namespace std;

/*****************************************************************************/
/*                              Definicje Klas                               */
/*****************************************************************************/
class klient
{
public:
    int id_kl;
    string imie, nazwisko, pesel, adres_zamieszkania, telefon;
public:
    klient( int new_id_kl, string new_imie, string new_nazwisko, string new_pesel, string new_adres_zamieszkania, string new_telefon )
    {
        id_kl = new_id_kl;
        imie = new_imie;
        nazwisko = new_nazwisko;
        pesel = new_pesel;
        adres_zamieszkania = new_adres_zamieszkania;
        telefon = new_telefon;
    } //konstruktor
    klient() { } //konstruktor bez argumentow
    ~klient() { } //destruktor
};

class ksiazka
{
public:
    int id_ks, stan;
    string autor, tytul, numer_seryjny;
public:
    ksiazka( int new_id_ks, string new_autor, string new_tytul, string new_numer_seryjny, int new_stan )
    {
        id_ks = new_id_ks;
        autor = new_autor;
        tytul = new_tytul;
        numer_seryjny = new_numer_seryjny;
        stan = new_stan;
    } //konstruktor
    ksiazka() { } //konstruktor bez argumentow
    ~ksiazka() { } //destruktor
};

class wypozyczone
{
public:
    int id_w, id_kl, id_ks;
public:
    wypozyczone( int new_id_w, int new_id_kl, int new_id_ks )
    {
        id_w = new_id_w;
        id_kl = new_id_kl;
        id_ks = new_id_ks;
    }
    wypozyczone() { } //konstruktor bez argumentow
    ~wypozyczone() { } //dekonstruktor
};

/*****************************************************************************/
/*                            Deklaracje Funkcji                             */
/*****************************************************************************/
bool wczytywanie_klient( ifstream & plik, vector < klient > & klient_t );
bool wczytywanie_ksiazka( ifstream & plik, vector < ksiazka > & ksiazka_t );
bool wczytywanie_wypozyczone( ifstream & plik, vector < wypozyczone > & wypozyczone_t );
bool zapisz_klient( ofstream & plik2, vector < klient > klient_t );
bool zapisz_ksiazka( ofstream & plik2, vector < ksiazka > & ksiazka_t );
bool zapisz_wypozyczone( ofstream & plik2, vector < wypozyczone > wypozyczone_t );
void wypisz_wypozyczone_ksiazki( vector < wypozyczone > wypozyczone_t, vector < klient > klient_t, vector < ksiazka > ksiazka_t );
void wypisz_ksiazki( vector < ksiazka > ksiazka_t );
void wypisz_klient( vector < klient > klient_t );
void sformatuj( string napis, int dlugosc );
string int_do_string( int i, string & napis );
void dodaj_klienta( vector < klient > & klient_t );
void dodaj_ksiazke( vector < ksiazka > & ksiazka_t );
void wypozycz_ksiazke( vector < klient > klient_t, vector < ksiazka > & ksiazka_t, vector < wypozyczone > & wypozyczone_t );
void oddaj_ksiazke( vector < klient > klient_t, vector < ksiazka > & ksiazka_t, vector < wypozyczone > & wypozyczone_t );
void zakoncz( bool & koniec );

/*****************************************************************************/
/*                              Program Główny                               */
/*****************************************************************************/
int main()
{
    /*                          Ustawienie Buforu Okna                          */
    HANDLE okno = GetStdHandle( STD_OUTPUT_HANDLE );
    COORD size;
    size.X = 130;
    size.Y = 2000;
    SetConsoleScreenBufferSize( okno, size );
    /*                               Zmienne                                    */
    ifstream plik; //zmienna ustawiona do odczytu
    ofstream plik2; //zmienna ustawiona do zapisu
    /*                    Wczytywanie danych do pamięci                         */
    vector < klient > klient_t;
    if( wczytywanie_klient( plik, klient_t ) ) return 1;
   
    vector < ksiazka > ksiazka_t;
    if( wczytywanie_ksiazka( plik, ksiazka_t ) ) return 1;
   
    vector < wypozyczone > wypozyczone_t;
    if( wczytywanie_wypozyczone( plik, wypozyczone_t ) ) return 1;
    /*                                    Menu                                    */
   
    /*                               Zapisywanie danych                           */
    zapisz_klient( plik2, klient_t );
    zapisz_ksiazka( plik2, ksiazka_t );
    zapisz_wypozyczone( plik2, wypozyczone_t );
    cin.sync();
    cin.get();
    return 0;
}

/*****************************************************************************/
/*                             Definicje Funkcji                             */
/*****************************************************************************/
bool wczytywanie_klient( ifstream & plik, vector < klient > & klient_t )
{
    int id_kl;
    string imie, nazwisko, pesel, adres_zamieszkania, telefon;
    plik.open( "klient.txt" );
    if( !plik.good() )
    {
        cout << "Brak dostepu do pliku 'klient.txt'. Aby zakonczyc nacisnij ENTER";
        cin.sync();
        cin.get();
        plik.close();
        plik.clear();
        return 1;
    }
    else
    {
        while( !plik.eof() )
        {
            plik >> id_kl >> imie >> nazwisko >> pesel >> adres_zamieszkania >> telefon;
            klient_t.push_back( klient( id_kl, imie, nazwisko, pesel, adres_zamieszkania, telefon ) );
        }
        plik.close();
        plik.clear();
        return 0;
    }
} // koniec wczytywanie_klient

bool wczytywanie_ksiazka( ifstream & plik, vector < ksiazka > & ksiazka_t )
{
    int id_ks, stan;
    string autor, tytul, numer_seryjny;
    plik.open( "ksiazka.txt" );
    if( !plik.good() )
    {
        cout << "Brak dostepu do pliku 'ksiazka.txt'. Aby zakonczyc nacisnij ENTER";
        cin.sync();
        cin.get();
        plik.close();
        plik.clear();
        return 1;
    }
    else
    {
        while( !plik.eof() )
        {
            plik >> id_ks >> autor >> tytul >> numer_seryjny >> stan;
            ksiazka_t.push_back( ksiazka( id_ks, autor, tytul, numer_seryjny, stan ) );
        }
        plik.close();
        plik.clear();
        return 0;
    }
} // koniec wczytywanie_ksiazka

bool wczytywanie_wypozyczone( ifstream & plik, vector < wypozyczone > & wypozyczone_t )
{
    int id_w, id_kl, id_ks;
    plik.open( "wypozyczone.txt" );
    if( !plik.good() )
    {
        cout << "Brak dostepu do pliku 'wypozyczone.txt'. Aby zakonczyc nacisnij ENTER";
        cin.sync();
        cin.get();
        plik.close();
        plik.clear();
        return 1;
    }
    else
    {
        while( !plik.eof() )
        {
            plik >> id_w >> id_kl >> id_ks;
            wypozyczone_t.push_back( wypozyczone( id_w, id_kl, id_ks ) );
        }
        plik.close();
        plik.clear();
        return 0;
    }
} // koniec wczytywanie_wypozyczone

bool zapisz_klient( ofstream & plik2, vector < klient > klient_t )
{
    int ile_klientow = klient_t.size();
    plik2.open( "klient.txt", ios::trunc );
    if( !plik2.good() )
    {
        cout << "Blad zapisu do pliku 'klient.txt'. Aby zakonczyc nacisnij ENTER";
        cin.sync();
        cin.get();
        plik2.close();
        plik2.clear();
        return 1;
    }
    else
    {
        for( int i = 0; i < ile_klientow; ++i )
        plik2 << endl << klient_t[ i ].id_kl << " " << klient_t[ i ].imie << " " << klient_t[ i ].nazwisko << " "
             << klient_t[ i ].pesel << " " << klient_t[ i ].adres_zamieszkania << " " << klient_t[ i ].telefon;
       
        plik2.close();
        plik2.clear();
        return 0;
    }
} //koniec zapisz_klient

bool zapisz_ksiazka( ofstream & plik2, vector < ksiazka > & ksiazka_t )
{
    int ile_ksiazek = ksiazka_t.size();
    plik2.open( "ksiazka.txt", ios::trunc );
    if( !plik2.good() )
    {
        cout << "Blad zapisu do pliku 'ksiazka.txt'. Aby zakonczyc nacisnij ENTER";
        cin.sync();
        cin.get();
        plik2.close();
        plik2.clear();
        return 1;
    }
    else
    {
        for( int i = 0; i < ile_ksiazek; ++i )
        plik2 << endl << ksiazka_t[ i ].id_ks << " " << ksiazka_t[ i ].tytul << " " << ksiazka_t[ i ].autor << " "
             << ksiazka_t[ i ].numer_seryjny << " " << ksiazka_t[ i ].stan;
       
        plik2.close();
        plik2.clear();
        return 0;
    }
} // koniec zapisz ksiazki

bool zapisz_wypozyczone( ofstream & plik2, vector < wypozyczone > wypozyczone_t )
{
    int ile_wypozyczone = wypozyczone_t.size();
    plik2.open( "wypozyczone.txt", ios::trunc );
    if( !plik2.good() )
    {
        cout << "Blad zapisu do pliku 'ksiazka.txt'. Aby zakonczyc nacisnij ENTER";
        cin.sync();
        cin.get();
        plik2.close();
        plik2.clear();
        return 1;
    }
    else
    {
        for( int i = 0; i < ile_wypozyczone; ++i )
             plik2 << endl << wypozyczone_t[ i ].id_w << " " << wypozyczone_t[ i ].id_kl << " " << wypozyczone_t[ i ].id_ks;
       
        plik2.close();
        plik2.clear();
        return 0;
    }
} //koniec zapisz wypozyczone

void wypisz_wypozyczone_ksiazki( vector < wypozyczone > wypozyczone_t, vector < klient > klient_t, vector < ksiazka > ksiazka_t )
{
    int ile_wypozyczone = wypozyczone_t.size();
    int ile_klientow = klient_t.size();
    int ile_ksiazek = ksiazka_t.size();
    string napis;
    cout << "ID     | Imie            | Nazwisko           | Adres                | Autor                    | Tytul ksiazki                |" << endl;
    cout << "-------------------------------------------------------------------------------------------------------------------------------|" << endl;
    for( int i = 0; i < ile_wypozyczone; ++i )
    {
        int_do_string( wypozyczone_t[ i ].id_w, napis );
        sformatuj( napis, 7 );
        for( int j = 0; j < ile_klientow; ++j )
        if( wypozyczone_t[ i ].id_kl == klient_t[ j ].id_kl )
        {
            sformatuj( klient_t[ j ].imie, 17 );
            sformatuj( klient_t[ j ].nazwisko, 20 );
            sformatuj( klient_t[ j ].adres_zamieszkania, 22 );
            break;
        }
        for( int j = 0; j < ile_ksiazek; ++j )
        if( wypozyczone_t[ i ].id_ks == ksiazka_t[ j ].id_ks )
        {
            sformatuj( ksiazka_t[ j ].autor, 26 );
            sformatuj( ksiazka_t[ j ].tytul, 30 );
            break;
        }
        cout << endl;
    }
   
    cout << "-------------------------------------------------------------------------------------------------------------------------------|" << endl;
    cin.sync();
    cin.get();
} //wypisz_wypozyczone_ksiazki

void sformatuj( string napis, int dlugosc )
{
    cout << napis;
    for( int k = napis.length(); k < dlugosc; ++k ) cout << " ";
   
    cout << "|";
} // koniec sformatuj

string int_do_string( int i, string & napis )
{
    stringstream ss;
    ss << i;
    ss >> napis;
    return napis;
} //koniec int_do_string

void dodaj_klienta( vector < klient > & klient_t )
{
    int id_kl;
    string imie, nazwisko, pesel, adres_zamieszkania, telefon;
    int ile_klientow = klient_t.size();
    bool zarejestrowany = false;
    cout << "Podaj pesel: ";
    cin >> pesel;
    for( int i = 0; i < ile_klientow; ++i )
    if( pesel == klient_t[ i ].pesel )
    {
        cout << "Jestes juz zarejestowany w bazie !";
        zarejestrowany = true;
        break;
    }
    if( !zarejestrowany )
    {
        id_kl =++ile_klientow;
        cout << "Podaj imie: ";
        cin >> imie;
        cout << "Podaj nazwisko: ";
        cin >> nazwisko;
        cout << "Podaj adres zamieszkania: ";
        cin >> adres_zamieszkania;
        cout << "Podaj numer telefonu: ";
        cin >> telefon;
        klient_t.push_back( klient( id_kl, imie, nazwisko, pesel, adres_zamieszkania, telefon ) );
    }
    cin.sync();
    cin.get();
} // koniec dodaj_klienta

void dodaj_ksiazke( vector < ksiazka > & ksiazka_t )
{
    int id_ks, stan, ile;
    string autor, tytul, numer_seryjny;
    int ile_ksiazek = ksiazka_t.size();
    bool zarejestrowany = false;
    char znak;
    cout << "Podaj numer seryjny ksizki: ";
    cin >> numer_seryjny;
    for( int i = 0; i < ile_ksiazek; ++i )
    if( numer_seryjny == ksiazka_t[ i ].numer_seryjny )
    {
        cout << "Ksiazka znajduje sie juz w ksiegarni, jej stan wynosi: " << ksiazka_t[ i ].stan << endl;
        cout << "Czy chcesz dodac wiecej takich samych ksiazek do biblioteki ? [t/n] ";
        cin >> znak;
        if( znak == 't' || znak == 'T' )
        {
            cout << "Podaj iosc eglemplarzy, ktore chcesz odac: ";
            cin >> ile;
            ksiazka_t[ i ].stan += ile;
            cout << "Po dodaniu stan wynosi: " << ksiazka_t[ i ].stan;
        }
        zarejestrowany = true;
        break;
    }
    if( !zarejestrowany )
    {
        id_ks = ksiazka_t[ ile_ksiazek - 1 ].id_ks + 1;
        cout << "Podaj autora: ";
        cin >> autor;
        cout << "Podaj tytul: ";
        cin >> tytul;
        cout << "Podaj ile ksiazek chcesz dodac: ";
        cin >> stan;
        ksiazka_t.push_back( ksiazka( id_ks, autor, tytul, numer_seryjny, stan ) );
    }
    cin.sync();
    cin.get();
} //koniec dodaj ksiazke

void wypozycz_ksiazke( vector < klient > klient_t, vector < ksiazka > & ksiazka_t, vector < wypozyczone > & wypozyczone_t )
{
    int ile_klientow = klient_t.size();
    int ile_ksiazek = ksiazka_t.size();
    int ile_wypozyczone = wypozyczone_t.size();
    string autor, tytul;
    int id_kl, id_w;
    id_w = wypozyczone_t[ ile_wypozyczone - 1 ].id_w + 1; //nowy identyfikator wypozyczenia
    bool zarejestrowany = false;
    bool ksiazka = false;
    cout << "Podaj identyfikator klienta: ";
    cin >> id_kl;
    for( int i = 0; i < ile_klientow; ++i )
    if( klient_t[ i ].id_kl == id_kl )
    {
        cout << "Podaj tytul i autora kisazki." << endl;
        cout << "Autor: ";
        cin >> autor;
        cout << "Tytul: ";
        cin >> tytul;
        for( int j = 0; j < ile_ksiazek; ++j )
        if( ksiazka_t[ j ].autor == autor && ksiazka_t[ j ].tytul == tytul )
        if( ksiazka_t[ j ].stan > 0 )
        {
            cout << "Wypozyczono ksiazke !";
            --ksiazka_t[ j ].stan;
            wypozyczone_t.push_back( wypozyczone( id_w, klient_t[ i ].id_kl, ksiazka_t[ j ].id_ks ) );
            ksiazka = true;
            break;
        }
        else cout << "Wszystkie egzemplarze zostaly wyporzyczone !";
       
        zarejestrowany = true;
        break;
    };
    if( !ksiazka ) cout << "Nie ma takiej ksiazki !";
   
    if( !zarejestrowany ) cout << "Osoby o podanym id nie ma w bazie. Prosze najpierw dodac klienta.";
   
    cin.sync();
    cin.get();
} //koniec wypozycz_ksiazke

void wypisz_ksiazki( vector < ksiazka > ksiazka_t )
{
    string napis;
    int ile_ksiazek = ksiazka_t.size();
    cout << "ID     | Autor                    | Tytul ksiazki                | Stan         | Numer seryjny       |" << endl;
    cout << "------------------------------------------------------------------------------------------------------|" << endl;
    for( int i = 0; i < ile_ksiazek; ++i )
    {
        int_do_string( ksiazka_t[ i ].id_ks, napis );
        sformatuj( napis, 7 );
        sformatuj( ksiazka_t[ i ].autor, 26 );
        sformatuj( ksiazka_t[ i ].tytul, 30 );
        int_do_string( ksiazka_t[ i ].stan, napis );
        sformatuj( napis, 14 );
        sformatuj( ksiazka_t[ i ].numer_seryjny, 21 );
        cout << endl;
    }
    cout << "------------------------------------------------------------------------------------------------------|" << endl;
    cin.sync();
    cin.get();
} //koniec wypisz_ksiazki

void wypisz_klient( vector < klient > klient_t )
{
    string napis;
    int ile_klientow = klient_t.size();
    cout << "ID     | Imie       | Nazwisko          | PESEL      | Adres zamieszkania  |Nr telefonu    |" << endl;
    cout << "-------------------------------------------------------------------------------------------|" << endl;
    for( int i = 0; i < ile_klientow; ++i )
    {
        int_do_string( klient_t[ i ].id_kl, napis );
        sformatuj( napis, 7 );
        sformatuj( klient_t[ i ].imie, 12 );
        sformatuj( klient_t[ i ].nazwisko, 19 );
        sformatuj( klient_t[ i ].pesel, 12 );
        sformatuj( klient_t[ i ].adres_zamieszkania, 21 );
        sformatuj( klient_t[ i ].telefon, 15 );
        cout << endl;
    }
    cout << "-------------------------------------------------------------------------------------------|" << endl;
    cin.sync();
    cin.get();
} //koniec wypisz_klient

void oddaj_ksiazke( vector < klient > klient_t, vector < ksiazka > & ksiazka_t, vector < wypozyczone > & wypozyczone_t )
{
    int id_w, j;
    int ile_wypozyczone = wypozyczone_t.size();
    int ile_ksizek = ksiazka_t.size();
    int ile_klientow = klient_t.size();
    char znak;
    bool znaleziono = false;
    cout << "Podaj id wypozyczenia: ";
    cin >> id_w;
    for( int i = 0; i < ile_wypozyczone; ++i )
    if( wypozyczone_t[ i ].id_w == id_w )
    {
        cout << id_w << " ";
        for( j = 0; j < ile_klientow; ++j )
        if( wypozyczone_t[ i ].id_kl == klient_t[ j ].id_kl )
        {
            cout << klient_t[ j ].imie << " " << klient_t[ j ].nazwisko << " ";
            break;
        }
        for( j = 0; j < ile_ksizek; ++j )
        if( wypozyczone_t[ i ].id_ks == ksiazka_t[ j ].id_ks )
        {
            cout << ksiazka_t[ j ].autor << " " << ksiazka_t[ j ].tytul;
            break;
        }
        cout << endl << "Czy aby na pewno chcesz oddac ksiazke ? t/n" << endl;
        cin >> znak;
        if( znak == 't' || znak == 'T' )
        {
            ksiazka_t[ j ].stan += 1;
            wypozyczone_t.erase( wypozyczone_t.begin() + i );
            cout << "Pomyslnie oddano ksiazke !";
        }
        znaleziono = true;
        break;
    }
    if( !znaleziono ) cout << "Nie odnaleziono wypozyczenia !";
   
    cin.sync();
    cin.get();
} //koniec oddaj_ksiazke

void zakoncz( bool & koniec )
{
    char znak;
    cout << "Czy aby napewno chcesz wyjsc z programu ? t/n" << endl;
    cin >> znak;
    if( znak == 't' || znak == 'T' ) koniec = true;
   
} // koniec zakoncz

Błąd kompilacji wygląda następująco:

C:\Dev-Cpp\Bin\..\lib\gcc\mingw32\3.4.2\..\..\..\..\mingw32\bin\ld.exe: BFD 2.15.91 20040904 internal error, aborting at ../../src/bfd/cache.c line 495 in bfd_cache_lookup_worker

C:\Dev-Cpp\Bin\..\lib\gcc\mingw32\3.4.2\..\..\..\..\mingw32\bin\ld.exe: Please report this bug.

collect2: ld returned 1 exit status

Execution terminated
P-20752
ison
» 2010-08-12 21:45:48
u mnie kompiluje dobrze...
coś masz zwalone z Mingw :p
P-20753
Dybusek
Temat założony przez niniejszego użytkownika
» 2010-08-12 21:51:09
Kompiluje się dobrze, tylko co kilka kompilacji wyskakuje ten błąd.
P-20754
ison
» 2010-08-12 21:56:10
ld returned 1 exit status

tego typu błąd może wyskakiwać jeśli już masz uruchomioną aplikację o tej samej nazwie i próbujesz kompilować kod. Error wyskakuje w wyniku tego iż ta aplikacja jest aktualnie używana zatem kompilator nie może jej zastąpić nowym plikiem(przy kompilacji). Zwyczajnie miej na uwadze przy kompilacji czy nie masz już tego programu na pasku zadań.
P-20755
Elaine
» 2010-08-12 22:32:17
ison, przeczytałeś treść błędu? Internal error w BFD nie może mieć związku z odmową dostępu do pliku. Problemem jest skopany toolchain, polecam aktualizację do nowszej wersji, mamy rok 2010, nie 2004.
P-20757
« 1 »
  Strona 1 z 1