Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > pl.comp.programming > #32453 > unrolled thread

Dziwny wyciek zasobów

Started bySzyk Cech <szykcech@spoko.pl>
First post2019-03-09 14:08 +0100
Last post2019-03-24 11:55 +0100
Articles 8 — 3 participants

Back to article view | Back to pl.comp.programming


Contents

  Dziwny wyciek zasobów Szyk Cech <szykcech@spoko.pl> - 2019-03-09 14:08 +0100
    Re: Dziwny wyciek zasobów Szyk Cech <szykcech@spoko.pl> - 2019-03-09 14:09 +0100
    Re: Dziwny wyciek zasobów Wojciech Muła <wojtek.mula@gmail.com> - 2019-03-10 13:38 -0700
      Re: Dziwny wyciek zasobów Szyk Cech <szykcech@spoko.pl> - 2019-03-23 14:37 +0100
        Re: Dziwny wyciek zasobów Wojciech Muła <wojtek.mula@gmail.com> - 2019-03-23 13:30 -0700
          Re: Dziwny wyciek zasobów Borneq <borneq@antyspam.hidden.pl> - 2019-03-23 21:49 +0100
            Re: Dziwny wyciek zasobów Wojciech Muła <wojtek.mula@gmail.com> - 2019-03-25 15:13 -0700
    Re: Dziwny wyciek zasobów Szyk Cech <szykcech@spoko.pl> - 2019-03-24 11:55 +0100

#32453 — Dziwny wyciek zasobów

FromSzyk Cech <szykcech@spoko.pl>
Date2019-03-09 14:08 +0100
SubjectDziwny wyciek zasobów
Message-ID<QUOgE.6781$WX2.6137@fx16.fr7>
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.Linux.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.Linux.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

[toc] | [next] | [standalone]


#32454

FromSzyk Cech <szykcech@spoko.pl>
Date2019-03-09 14:09 +0100
Message-ID<qWOgE.6818$WX2.3396@fx16.fr7>
In reply to#32453
Sorry ntg. miało iść na: pl.comp.os.linux.programowanie

[toc] | [prev] | [next] | [standalone]


#32455

FromWojciech Muła <wojtek.mula@gmail.com>
Date2019-03-10 13:38 -0700
Message-ID<42388eba-da05-48f0-ad07-2587468ba142@googlegroups.com>
In reply to#32453
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.

[toc] | [prev] | [next] | [standalone]


#32467

FromSzyk Cech <szykcech@spoko.pl>
Date2019-03-23 14:37 +0100
Message-ID<NEqlE.145642$Gr1.106458@fx05.fr7>
In reply to#32455
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...

[toc] | [prev] | [next] | [standalone]


#32468

FromWojciech Muła <wojtek.mula@gmail.com>
Date2019-03-23 13:30 -0700
Message-ID<b099e30f-4f7b-4e88-9ada-d2324374bc06@googlegroups.com>
In reply to#32467
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_initialization

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.

[toc] | [prev] | [next] | [standalone]


#32469

FromBorneq <borneq@antyspam.hidden.pl>
Date2019-03-23 21:49 +0100
Message-ID<q7663u$bos$1@node1.news.atman.pl>
In reply to#32468
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_initialization
> 
> 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?

[toc] | [prev] | [next] | [standalone]


#32474

FromWojciech Muła <wojtek.mula@gmail.com>
Date2019-03-25 15:13 -0700
Message-ID<93edd4e0-f76d-4551-89a6-58512924aaef@googlegroups.com>
In reply to#32469
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_initialization
> > 
> > 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.

[toc] | [prev] | [next] | [standalone]


#32470

FromSzyk Cech <szykcech@spoko.pl>
Date2019-03-24 11:55 +0100
Message-ID<XmJlE.108206$2F3.9901@fx20.fr7>
In reply to#32453
Problem dotyczył praw pliku: kopiowałem plik z uprawnieniami r--r--r-- i 
chciałem go otworzyć do pisania.

[toc] | [prev] | [standalone]


Back to top | Article view | pl.comp.programming


csiph-web