Wycieki pamięci i zapis do pliku

0

Witam kończę właśnie projekt programistyczny i mam dwa pytania:

1.Dlaczego nie chce zadziałać mi zwalnianie pamięci?

2.Jak utworzyć funkcję odpowiadającą za zapis list jednkoierunkowych(pasażerów na dany lot) do plików(W moim przypadku to funkcja saveToFiles, jednak to raczej nie ma prawa działać, a może wystarczy tylko jakaś korekta?)
Oto kod:

#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <optional>
#include <conio.h>
#include <cassert>
 
using namespace std;
 
//pozycja na liście pasażerów
struct PasazerListItem {
    string imie;
    string nazwisko;
    unsigned numerMiejsca;
    PasazerListItem* nextPasazer;
};
 
//pozycja na liście lotów
struct LotListItem {
    string symbol;
    PasazerListItem* firstPasazer;
    LotListItem* nextLot;
};
 
//dane z pliku
struct Record {
    string symbol;
    tm data;
    string odlot;
    string przylot;
    string imie;
    string nazwisko;
    unsigned numerMiejsca;
    Record* next;
};
 
Record parse_record(const string& str)
{
    Record record{};                    //tworzenie obiektu struktury o nazwie record
    istringstream ss{ str };
 
    ss >> record.symbol
        >> get_time(&(record.data), "%d.%m.%Y")
        >> record.odlot
        >> record.przylot
        >> record.imie
        >> record.nazwisko
        >> record.numerMiejsca;
 
    if (!ss)
    {
        cerr << "Bledny rekord danych!";
        exit(0);
    }
 
    return record;
}
 
void show_record(const Record& record) {
    cout << "Symbol Lotu: " << record.symbol << '\n'
        << "Data:      " << put_time(&(record.data), "%d-%m-%Y") << '\n'
        << "Odlot: " << record.odlot << '\n'
        << "Przylot:  " << record.przylot << '\n'
        << "Imie:      " << record.imie << '\n'
        << "Nawisko:   " << record.nazwisko << '\n'
        << "Miejsce:     " << record.numerMiejsca << '\n';
}
 
//funkcja dodaje lot i pasażera do lotu
void add_lot_pasazer(LotListItem* head, const Record& record)
{
    LotListItem* itemLot = head;
    LotListItem* nowyLot = nullptr;
    PasazerListItem* itemPasazer = nullptr;
    PasazerListItem* nowyPasazer = nullptr;
 
    if (itemLot->symbol == "")
    {
        itemLot->symbol = record.symbol;
    }
    else
    {
        while (itemLot->symbol != record.symbol)
        {
            if (itemLot->nextLot == nullptr)
            {
                nowyLot = new LotListItem();
                nowyLot->symbol = record.symbol;
                nowyLot->firstPasazer = nullptr;
                nowyLot->nextLot = nullptr;
                itemLot->nextLot = nowyLot;
                itemLot = nowyLot;
                break;
            }
            else
            {
                itemLot = itemLot->nextLot;
            }
        }
    }
 
    if (itemLot->firstPasazer == nullptr)
    {
        PasazerListItem* nowyPasazer = new PasazerListItem();
        nowyPasazer->imie = record.imie;
        nowyPasazer->nazwisko = record.nazwisko;
        nowyPasazer->numerMiejsca = record.numerMiejsca;
        nowyPasazer->nextPasazer = nullptr;
        itemLot->firstPasazer = nowyPasazer;
    }
    else
    {
        itemPasazer = itemLot->firstPasazer;
        while (itemPasazer->nextPasazer != nullptr)
            itemPasazer = itemPasazer->nextPasazer;
 
        PasazerListItem* nowyPasazer = new PasazerListItem();
        nowyPasazer->imie = record.imie;
        nowyPasazer->nazwisko = record.nazwisko;
        nowyPasazer->numerMiejsca = record.numerMiejsca;
        nowyPasazer->nextPasazer = nullptr;
        itemPasazer->nextPasazer = nowyPasazer;
    }
}
 
 
 
//wyświetla na ekranie listę lotów wraz z przypisanymi pasażerami
void show_all(LotListItem* head)
{
    LotListItem* itemLot = head;
    PasazerListItem* itemPasazer = nullptr;
 
    if (itemLot->symbol != "")
    {
        do
        {
            cout << "Symbol Lotu: " << itemLot->symbol << endl;
            if (itemLot->firstPasazer != nullptr)
            {
                itemPasazer = itemLot->firstPasazer;
                while (itemPasazer->nextPasazer != nullptr)
                {
                    cout << " PASAZER: " << itemPasazer->imie << " " << itemPasazer->nazwisko << " " << itemPasazer->numerMiejsca << endl;
                    itemPasazer = itemPasazer->nextPasazer;
                }
 
                cout << " PASAZER: " << itemPasazer->imie << " " << itemPasazer->nazwisko << " " << itemPasazer->numerMiejsca << endl;
            }
            else
            {
                cout << " * BRAK PASAZEROW *" << '\n';
            }
 
            itemLot = itemLot->nextLot;
        } while (itemLot != nullptr);
    }
}
 
void saveToFiles(const Record& record)  //liste pasazerow zapisac do plikow BER LON MAD 
{
    while (!false)
    {
        fstream file{ "DaneLotu.txt" };
        if (!file) {
            cout << "Blad otwarcia pliku!\n";
        }
        string line;
        getline(file, line);
        const auto record = parse_record(line);
        //show_record(record);
        //cout << '\n';
        //_getch();
        string BER = "BER", AMS = "AMS", LON = "LON", MAD = "MAD";
        if (record.symbol == BER)
        {
            fstream pliczek;
            pliczek.open("BER.txt", ios::app);
            cout << record.symbol;
            pliczek.close();
        }
        if (record.symbol == AMS)
        {
            fstream pliczek;
            pliczek.open("AMS.txt", ios::app);
 
            pliczek.close();
        }
        if (record.symbol == LON)
        {
            fstream pliczek;
            pliczek.open("LON.txt", ios::app);
 
            pliczek.close();
 
        }
        if (record.symbol == MAD)
        {
            fstream pliczek;
            pliczek.open("MAD.txt", ios::app);
 
            pliczek.close();
 
        }
        _getch();
    }
 
}
 
 
void usunListeIteracyjnie(LotListItem* head)
{
    LotListItem* itemLot = head;
    PasazerListItem* itemPasazer = nullptr;
    while (head)
    {
        auto p = head->nextLot;
        delete head;
        head = p;
    }
}
 
int main() 
{
    LotListItem* head = new LotListItem;
    head->symbol = "";
    head->firstPasazer = nullptr;
    head->nextLot = nullptr;
 
    fstream file{ "DaneLotu.txt" };
    if (!file) {
        cout << "Blad otwarcia pliku!\n";
        return 0;
    }
 
    while (!false)
    {
        string line;
        getline(file, line);
        if (line == "")
            break;
        const auto record = parse_record(line);
        show_record(record);
        add_lot_pasazer(head, record);
        cout << '\n';
    }
 
    show_all(head);
 
     
    //zapisanie do plików
    //saveToFiles(record);
     
     
 
    //zwolnienie pamięci
    usunListeIteracyjnie(head);
    cout << _CrtDumpMemoryLeaks();
}

Program to generalnie baza lotów na lotnisku, zczytuje z jednego pliku i zapisuje do mniejszych z podziałem na symbole. Ponadto w tych mniejszych plikach osoby w pliku muszą być posortowane ze wzgledu na miejsca.

0
kaminie318 napisał(a):

Witam kończę właśnie projekt programistyczny i mam dwa pytania:

1.Dlaczego nie chce zadziałać mi zwalnianie pamięci?

Co to znaczy? Rozumiem, że _Crtcośtam memory leaks zwraca ci coś innego niż 0? Podaj, dla jakich danych wejściowych tak się dzieje, bo u mnie jest 0, ale sobie wpisałem jakieś dane sam, pokaż swoje.

0
sugar_hiccup napisał(a):
kaminie318 napisał(a):

Witam kończę właśnie projekt programistyczny i mam dwa pytania:

1.Dlaczego nie chce zadziałać mi zwalnianie pamięci?

Co to znaczy? Rozumiem, że _Crtcośtam memory leaks zwraca ci coś innego niż 0? Podaj, dla jakich danych wejściowych tak się dzieje, bo u mnie jest 0, ale sobie wpisałem jakieś dane sam, pokaż swoje.

To są cztery linijki z mojego głównego pliku tekstowego na którym opiera się program:
MAD 14.12.2019 CHOPINA BAJARAS GRZEGORZ BORUCKI 444
BER 23.12.2019 BALICE TEGEL MARTYNA BARTOSZEWSKA 786
AMS 22.12.2019 PYZOWICE SCHINPHOL HALINA KLOS 54
LON 11.10.2019 MODLIN HEATHROW MARZENA MALINIAK 145

0
void usunListeIteracyjnie(LotListItem* head)
{
    LotListItem* itemLot = head;
    PasazerListItem* itemPasazer = nullptr;
    while (head)
    {
        auto p = head->nextLot;
        delete head->firstPasazer; // Tutaj zapomniałeś usunąć pole struktury, któremu też zaalokowałeś pamięć
        delete head;
        head = p;
    }
}

Poza tym head to trochę myląca nazwa na wskaźnik, który porusza się po całej liście (oczywiście rozumiem, że po usunięciu, następnik jest nową głową, ale nadal trochę mało czytelne).

Co ciekawe, ten _CrtDumpMemoryLeaks nadal mi pokazywał 0 wycieków. Dopiero jak skompilowałem sobie na maku, to dostałem, co chciałem. Z jednej strony ciekawe czemu, z drugiej jakoś nie chce mi się zgłębiać zawiłości WinAPI.

0
sugar_hiccup napisał(a):
void usunListeIteracyjnie(LotListItem* head)
{
    LotListItem* itemLot = head;
    PasazerListItem* itemPasazer = nullptr;
    while (head)
    {
        auto p = head->nextLot;
        delete head->firstPasazer; // Tutaj zapomniałeś usunąć pole struktury, któremu też zaalokowałeś pamięć
        delete head;
        head = p;
    }
}

Poza tym head to trochę myląca nazwa na wskaźnik, który porusza się po całej liście (oczywiście rozumiem, że po usunięciu, następnik jest nową głową, ale nadal trochę mało czytelne).

Co ciekawe, ten _CrtDumpMemoryLeaks nadal mi pokazywał 0 wycieków. Dopiero jak skompilowałem sobie na maku, to dostałem, co chciałem. Z jednej strony ciekawe czemu, z drugiej jakoś nie chce mi się zgłębiać zawiłości WinAPI.

Poza tym head to trochę myląca nazwa na wskaźnik, który porusza się po całej liście (oczywiście rozumiem, że po usunięciu, następnik jest nową głową, ale nadal trochę mało czytelne).

0

Kurde,nie działa :( W Visualu dosc ze na konsoli wywala jedynke, to jeszcze w danych wyjsciowych detected memory leaks :(

0

A nie możesz po prostu użyć std::forward_list?

0
tajny_agent napisał(a):

A nie możesz po prostu użyć std::forward_list?

Nie mogę używać bibliotecznych kontenerów :/

1 użytkowników online, w tym zalogowanych: 0, gości: 1