PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : fdopen Speicher freigeben ohne Handle zu schließen?



7.e.Q
12-01-2006, 10:03
Hi Leute,

wie kann ich den von fdopen für die FILE* Struktur alloziierten Speicher wieder freigeben, ohne das File Handle zu schließen?




int fd = Server.GetFD();
FILE* fFile = fdopen(fd, "r");

// Datei-Operationen

fclose(fFile); // Schließt auch das Handle fd... das darf nicht passieren!
// Ich will hier nur den Speicher freigeben, der für fFile alloziiert wurde.

SeeksTheMoon
12-01-2006, 10:54
versuch mal obs mit free klappt. Falls nicht, dann kannst Du versuchen den Dateizeiger zu sichern, dann fclose und dann wieder zurückkopieren.
Oder Du musst die Low-Level Dateioperationen probieren.
Falls das alles nicht geht, dann soll es wohl so sein =)

7.e.Q
12-01-2006, 11:04
free hab ich schon versucht. Ging nicht. Hab jetzt Low-Level I/O. Aber ich würde gern für die Ausgabe lieber fprintf verwenden, als write. Irgendwie muss das doch möglich sein, den Speicher wieder freizugeben. Ich brauch die FILE* Struct halt nur temporär, während das FileHandle permanent ist.

Joghurt
12-01-2006, 14:23
Dupliziere einfach das Filehandle:
#include <stdio.h>
#include <unistd.h>

int main()
{
FILE* f = fopen("/tmp/foobar","wb");
int handle;
fwrite("Foo\n", 4, 1, f);
handle = dup(fileno(f));
fclose(f);
write(handle,"abc\n",4);
close(handle);
}

Joghurt
12-01-2006, 14:26
Nachtrag: du kannst das handle danach auch wieder in ein FILE* umwandeln, einfach
f = fdopen(handle,"wb");

7.e.Q
13-01-2006, 04:29
Du hast das falsch verstanden, Joghurt: ich habe ein Handle, aus dem ich ein FILE* mache, um darauf ein fprintf ausführen zu können. Nach dem fprintf möchte ich den Speicher, der für die FILE* Struktur reserviert wurde wieder freigeben, ohne das Handle zu schließen.

Duplizieren ist jedoch trotzdem eine gute Idee. Erst duplizieren, dann mit der Kopie und fdopen das FILE* öffnen und selbiges nach dem fprintf wieder schließen... das müsste ja auch das original Handle verschonen.

Danke

Joghurt
13-01-2006, 14:43
Duplizieren ist jedoch trotzdem eine gute Idee. Erst duplizieren, dann mit der Kopie und fdopen das FILE* öffnen und selbiges nach dem fprintf wieder schließen... das müsste ja auch das original Handle verschonen.Genau.

Ich hab mir jetzt nicht die Implementation von fclose der libc angeschaut, aber ich vermute mal, dass sie in etwa "fflush(file); close(fileno(file)); free(file);" macht. Mit einem fflush gefolgt von einem free könntest du dasselbe erreichen.

panzi
15-01-2006, 15:28
Mach lieber das:


#include <unistd.h>
#include <stdio.h>
...
int fd = -1;
FILE * fp = NULL;
...
fp = fdopen(fd,"wb");
...
fd = dup(fd);
fclose(fp);

7.e.Q
16-01-2006, 06:29
Warum, panzi?

Das Duplikat eines FD für fdopen zu verwenden, kommt doch auf's selbe raus oder nicht?

Joghurt
16-01-2006, 15:24
Das Duplikat eines FD für fdopen zu verwenden, kommt doch auf's selbe raus oder nicht?Ja, du sparst dir nur eine Variable ;)

Und bekommst Probleme, wenn dup fehlschlägt und -1 zurückliefert. In dem Falle hast du nämlich den original fp nicht mehr.

Heutzutage ist RAM billig, von daher würde ich mit einer "richtigen" Kopie arbeiten.

panzi
16-01-2006, 16:00
Ja, du sparst dir nur eine Variable ;)

Und bekommst Probleme, wenn dup fehlschlägt und -1 zurückliefert. In dem Falle hast du nämlich den original fp nicht mehr.

Heutzutage ist RAM billig, von daher würde ich mit einer "richtigen" Kopie arbeiten.
jo eh. hab nur das posting oben übersehn, woeh schon wer das mit den fd duplizieren gsagt hat. dieser code ist ja im fehlerfall natürl. net gut.

7.e.Q
19-01-2006, 05:54
Ja, du sparst dir nur eine Variable ;)

Und bekommst Probleme, wenn dup fehlschlägt und -1 zurückliefert. In dem Falle hast du nämlich den original fp nicht mehr.

Heutzutage ist RAM billig, von daher würde ich mit einer "richtigen" Kopie arbeiten.

RAM ist nur in Standard-PCs billig. Für die Systeme, auf denen besagtes Programm läuft, ist dem leider nicht so.

Aber ich danke euch für die Hilfe bei der Lösungsfindung! :) Wüsste nicht, was ich ohne (unter anderem) dieses Forum machen würde.

RHBaum
20-01-2006, 12:33
Was ich ned verstehe :

FILE * iss doch nur ne struct mit infos zur physikalischen datei ....
+ nen zeiger auf nen Filepuffer

Die infos aus der Struct brauchst doch prizipiell fuer jede dateioperation, auch fuers physikalische schliessen ....

Das einzige was an speicher sparen koenntest, wenn das file quasi inaktiv ist, ist der Puffer ...

mit flush leerst den puffer, aber glaub den speicher gibst damit nich frei ....
Weiss nich, gibts da nich BS spezifische Befehle um den buffer zu verwalten ?

Gibt es nicht modi wo man ne datei ungepuffert oeffnet ? (Dann sollte der gesamte Speicherverbrauch deines File Descriptors ziemlich gering bleiben)

Zwischen den Filesystemspez. operationen und den Standard files gibt es meistens noch ne BS spezifische Schicht mit mehr kontrolle, ungepuffert natuerlich.
Memory Mapped File IO .... Sprich du blendest dateiinhalt bestimmter groesse und von bestimmter postion in deinem spicher ein, Waehrend die operationen nicht brauchst, haelst nur das Handle aufs File und die position, den speicher kannst komplett freigeben ...

Ob du nun mit fprintf auf den puffer oder mit sprintf direkt aufn Speicher malst, sollte dir nicht so viel unbehagen bereiten ....

Ciao ....