Thread View: pl.comp.programming
8 messages
8 total messages
Started by Szyk Cech
Sat, 09 Mar 2019 13:08
Dziwny wyciek zasobów
Author: Szyk Cech
Date: Sat, 09 Mar 2019 13:08
Date: Sat, 09 Mar 2019 13:08
116 lines
5052 bytes
5052 bytes
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
Re: Dziwny wyciek zasobów
Author: Szyk Cech
Date: Sat, 09 Mar 2019 13:09
Date: Sat, 09 Mar 2019 13:09
1 lines
1064 bytes
1064 bytes
Sorry ntg. miało iść na: pl.comp.os.linux.programowanie
Re: Dziwny wyciek zasobów
Author: Wojciech Muła
Date: Sun, 10 Mar 2019 20:38
Date: Sun, 10 Mar 2019 20:38
15 lines
1914 bytes
1914 bytes
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.
Re: Dziwny wyciek zasobów
Author: Szyk Cech
Date: Sat, 23 Mar 2019 13:37
Date: Sat, 23 Mar 2019 13:37
8 lines
1373 bytes
1373 bytes
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...
Re: Dziwny wyciek zasobów
Author: Wojciech Muła
Date: Sat, 23 Mar 2019 20:30
Date: Sat, 23 Mar 2019 20:30
17 lines
2099 bytes
2099 bytes
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.
Re: Dziwny wyciek zasobów
Author: Borneq
Date: Sat, 23 Mar 2019 20:49
Date: Sat, 23 Mar 2019 20:49
20 lines
1877 bytes
1877 bytes
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?
Re: Dziwny wyciek zasobów
Author: Szyk Cech
Date: Sun, 24 Mar 2019 10:55
Date: Sun, 24 Mar 2019 10:55
2 lines
1121 bytes
1121 bytes
Problem dotyczył praw pliku: kopiowałem plik z uprawnieniami r--r--r-- i chciałem go otworzyć do pisania.
Re: Dziwny wyciek zasobów
Author: Wojciech Muła
Date: Mon, 25 Mar 2019 22:13
Date: Mon, 25 Mar 2019 22:13
31 lines
2705 bytes
2705 bytes
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.
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads