eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.comp.programming › Dziwny wyciek zasobów
Ilość wypowiedzi w tym wątku: 8

  • 1. Data: 2019-03-09 14:08:00
    Temat: Dziwny wyciek zasobów
    Od: Szyk Cech <s...@s...pl>

    Witam

    [WSTĘP]
    Mam program w C++ oparty na bibliotece Qt. Generalnie program jest
    niezależny od systemu operacyjnego. Jednak z jakichś dziwnych względów
    biblioteka Qt nie ma możliwości operowania na datach plików i katalogów.
    Dlatego napisałem funkcję w oparciu o Api Linux-a realizującą kopiowanie
    dat plików. Jest to przydatne podczas kopiowania.

    [PROBLEM]
    Mam jakiś wyciek zasobów. W pewnym momencie operacja fopen się nie udaje
    (po całkiem sporej liczbie poprawnych operacji). Wg mnie wszystko
    powinno grać, ale błąd występuje.

    [KOD]
    Oto kod mojej funkcji:

    void gCopyFileAtributes(QString aSource, QString aDest)
    {
    if(!QFileInfo::exists(aSource))
    NOTIFY_EXCEPTION(QObject::tr("Source file does not exists:
    %1").arg(aSource), gLibraryId, eErrorCode::eFileSystemError);
    if(!QFileInfo::exists(aDest))
    NOTIFY_EXCEPTION(QObject::tr("Destination file does not exists:
    %1").arg(aDest), gLibraryId, eErrorCode::eFileSystemError);

    FILE* lSrc = fopen(aSource.toUtf8(), "r");
    if(!lSrc)
    NOTIFY_EXCEPTION(QObject::tr("fopen failed for file: %1:
    %2").arg(aSource).arg(strerror(errno)), gLibraryId,
    eErrorCode::eFileSystemError);

    FILE* lDest = fopen(aDest.toUtf8(), "w");
    if(!lDest)
    {
    fclose(lSrc);
    NOTIFY_EXCEPTION(QObject::tr("fopen failed for file: %1:
    %2").arg(aDest).arg(strerror(errno)), gLibraryId,
    eErrorCode::eFileSystemError);
    }

    struct stat lStat;
    if(fstat(fileno(lSrc),&lStat))
    {
    fclose(lSrc);
    fclose(lDest);
    NOTIFY_EXCEPTION(QObject::tr("fstat failed for file: %1:
    %2").arg(aSource).arg(strerror(errno)), gLibraryId,
    eErrorCode::eFileSystemError);
    }


    // Update to the same uid/gid
    if(fchown(fileno(lDest), lStat.st_uid,lStat.st_gid))
    {
    fclose(lSrc);
    fclose(lDest);
    NOTIFY_EXCEPTION(QObject::tr("fchown failed:
    %1").arg(strerror(errno)), gLibraryId, eErrorCode::eFileSystemError);
    }

    // Update the permissions
    if(fchmod(fileno(lDest), lStat.st_mode))
    {
    fclose(lSrc);
    fclose(lDest);
    NOTIFY_EXCEPTION(QObject::tr("fchmod failed:
    %1").arg(strerror(errno)), gLibraryId, eErrorCode::eFileSystemError);
    }

    // Change access time
    timeval lTimes[2];
    lTimes[0].tv_sec = lStat.st_atim.tv_sec;
    quint32 lUsecA(static_cast<quint32>(lStat.st_atim.tv_nsec / 1000));
    lTimes[0].tv_usec = lUsecA;

    // Change modification time
    lTimes[1].tv_sec = lStat.st_mtim.tv_sec;
    quint32 lUsecM(static_cast<quint32>(lStat.st_mtim.tv_nsec / 1000));
    lTimes[1].tv_usec = lUsecM;

    if(futimes(fileno(lDest), lTimes))
    {
    fclose(lSrc);
    fclose(lDest);
    NOTIFY_EXCEPTION(QObject::tr("futimes failed:
    %1").arg(strerror(errno)), gLibraryId, eErrorCode::eFileSystemError);
    }

    fclose(lSrc);
    fclose(lDest);
    }

    [OPIS FUNCKCJI]
    Jak widać wszystko tworzone jest na stosie z wyjątkiem 2 zmiennych lSrc
    i lDest. Jednak one są zawsze zwalniane i po za tym wyjątki nie są
    zgłaszane w trakcie wcześniejszej pracy.

    [OPIS ZGŁASZANEGO BŁĘDU]
    File: ../../../../Kopia3/Src/Libs/Common/Src/FileTools.Lin
    ux.cpp, in
    line: 26, in function: gCopyFileAtributes
    Error code: 3, Error message: fopen failed for file:
    /tmp/Kopia/!-dokumenty 2019-03-09 13-17-03/Programowanie/Qt/C++ GUI
    Programming with Qt 4/qt-book/chap06/mdieditor/images/new.png: Brak dostępu
    Exception occurs! Sender: Common.so, Error code: 3
    Message:
    File: ../../../../Kopia3/Src/Libs/Common/Src/FileTools.Lin
    ux.cpp, in
    line: 26, in function: gCopyFileAtributes
    Error code: 3, Error message: fopen failed for file:
    /tmp/Kopia/!-dokumenty 2019-03-09 13-17-03/Programowanie/Qt/C++ GUI
    Programming with Qt 4/qt-book/chap06/mdieditor/images/new.png: Brak dostępu
    Bug report has been sent...

    Może ktoś doradzi jak prawidłowo powinna wyglądać ta funkcja?
    dzięki i pozdro
    Szyk Cech


  • 2. Data: 2019-03-09 14:09:42
    Temat: Re: Dziwny wyciek zasobów
    Od: Szyk Cech <s...@s...pl>

    Sorry ntg. miało iść na: pl.comp.os.linux.programowanie


  • 3. Data: 2019-03-10 21:38:03
    Temat: Re: Dziwny wyciek zasobów
    Od: Wojciech Muła <w...@g...com>

    On Saturday, March 9, 2019 at 2:08:03 PM UTC+1, Szyk Cech wrote:
    > Może ktoś doradzi jak prawidłowo powinna wyglądać ta funkcja?
    > dzięki i pozdro

    Weź to jak człowiek trzymaj w unique_ptr z własnym deleterem,
    to unikniesz wycieków (jeśli jakieś są, bo nie zauważyłem
    w tym kodzie).

    auto closefile = [](FILE* f){fclose(f);};
    std::unique_ptr<FILE, decltype(closefile)> infile{fopen("path", "r"), closefile};

    Wtedy przestajesz się martwić, czy i kiedy wołać fclose,
    bo to zrobi za Ciebie destruktor unique_ptr.

    w.


  • 4. Data: 2019-03-23 14:37:49
    Temat: Re: Dziwny wyciek zasobów
    Od: Szyk Cech <s...@s...pl>

    Dzięki!
    Mam jedno pytanie:

    > auto closefile = [](FILE* f){fclose(f);};
    > std::unique_ptr<FILE, decltype(closefile)> infile{fopen("path", "r"), closefile};

    Czemu w drugiej linii stosujesz nawiasy klamrowe?!? Przecież to nie jest
    ani funkcja ani inicjalizacja tablicy...


  • 5. Data: 2019-03-23 21:30:11
    Temat: Re: Dziwny wyciek zasobów
    Od: Wojciech Muła <w...@g...com>

    On Saturday, March 23, 2019 at 2:37:53 PM UTC+1, Szyk Cech wrote:
    > Dzięki!
    > Mam jedno pytanie:
    >
    > > auto closefile = [](FILE* f){fclose(f);};
    > > std::unique_ptr<FILE, decltype(closefile)> infile{fopen("path", "r"), closefile};
    >
    > Czemu w drugiej linii stosujesz nawiasy klamrowe?!? Przecież to nie jest
    > ani funkcja ani inicjalizacja tablicy...

    Od C++11 można, to się nazywa "uniform initialization":
    https://en.wikipedia.org/wiki/C%2B%2B11#Uniform_init
    ialization

    W ogóle ten kod można jeszcze uprościć, dopiero sam niedawno się tego dowiedziałem.
    Wystarczy jedna linijka, bez lambdy:

    std::unique_ptr<FILE, int(*)(FILE*)> infile{fopen("path", "r"), fclose};

    w.


  • 6. Data: 2019-03-23 21:49:04
    Temat: Re: Dziwny wyciek zasobów
    Od: Borneq <b...@a...hidden.pl>

    W dniu 23.03.2019 o 21:30, Wojciech Muła pisze:
    > On Saturday, March 23, 2019 at 2:37:53 PM UTC+1, Szyk Cech wrote:
    >> Dzięki!
    >> Mam jedno pytanie:
    >>
    >>> auto closefile = [](FILE* f){fclose(f);};
    >>> std::unique_ptr<FILE, decltype(closefile)> infile{fopen("path", "r"), closefile};
    >>
    >> Czemu w drugiej linii stosujesz nawiasy klamrowe?!? Przecież to nie jest
    >> ani funkcja ani inicjalizacja tablicy...
    >
    > Od C++11 można, to się nazywa "uniform initialization":
    https://en.wikipedia.org/wiki/C%2B%2B11#Uniform_init
    ialization
    >
    > W ogóle ten kod można jeszcze uprościć, dopiero sam niedawno się tego dowiedziałem.
    Wystarczy jedna linijka, bez lambdy:
    >
    > std::unique_ptr<FILE, int(*)(FILE*)> infile{fopen("path", "r"), fclose};
    >
    > w.
    >
    A nie lepszy kod mniej uproszczony a bardziej czytelny?


  • 7. Data: 2019-03-24 11:55:51
    Temat: Re: Dziwny wyciek zasobów
    Od: Szyk Cech <s...@s...pl>

    Problem dotyczył praw pliku: kopiowałem plik z uprawnieniami r--r--r-- i
    chciałem go otworzyć do pisania.


  • 8. Data: 2019-03-25 23:13:21
    Temat: Re: Dziwny wyciek zasobów
    Od: Wojciech Muła <w...@g...com>

    On Saturday, March 23, 2019 at 9:49:03 PM UTC+1, Borneq wrote:
    > W dniu 23.03.2019 o 21:30, Wojciech Muła pisze:
    > > On Saturday, March 23, 2019 at 2:37:53 PM UTC+1, Szyk Cech wrote:
    > >> Dzięki!
    > >> Mam jedno pytanie:
    > >>
    > >>> auto closefile = [](FILE* f){fclose(f);};
    > >>> std::unique_ptr<FILE, decltype(closefile)> infile{fopen("path", "r"),
    closefile};
    > >>
    > >> Czemu w drugiej linii stosujesz nawiasy klamrowe?!? Przecież to nie jest
    > >> ani funkcja ani inicjalizacja tablicy...
    > >
    > > Od C++11 można, to się nazywa "uniform initialization":
    https://en.wikipedia.org/wiki/C%2B%2B11#Uniform_init
    ialization
    > >
    > > W ogóle ten kod można jeszcze uprościć, dopiero sam niedawno się tego
    dowiedziałem. Wystarczy jedna linijka, bez lambdy:
    > >
    > > std::unique_ptr<FILE, int(*)(FILE*)> infile{fopen("path", "r"), fclose};
    > >
    > > w.
    > >
    > A nie lepszy kod mniej uproszczony a bardziej czytelny?

    Można jeszcze inaczej:

    std::unique_ptr<FILE, decltype(&fclose)> infile{fopen("path", "r"), fclose};

    Ale masz 100% rację, że to wciąż koślawy zapis. Chwilę mi zajęło,
    zanim doszedłem do powyższego zapisu. Lambda najbardziej oczywista
    i co więcej GCC ładnie ją inlinuje.

    w.

strony : [ 1 ]


Szukaj w grupach

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: