Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Eine Log-Funktion

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
16.07.2008, 16:39 Uhr
banshee



Ich habe in fremdem source code folgende Funktion zur Ausgabe in eine log-Datei gefunden:


C++:
void printfLog(const char* p_format,
               ...)
{
    char* p_text = new char[16384];
    p_text[0] = 0;
    va_list vaList;

    va_start(vaList, p_format);
    vsprintf(p_text, p_format, vaList);
    va_end(vaList);

    FILE* p_file = fopen("log.txt", "at");
    fprintf(p_file, "%s", p_text);

    delete[] p_text;
}


Und dazu hab ich zwei Fragen:

1) Warum wird p_text mit new/delete angelegt? Hat das irgendwelche Vorteile gegenüber dem ganz normalen char* p_text[16384] ?

2) Sehe ich das richtig, dass p_text[0] für den Fall dass keine Argumente in der Parameterliste sind, auf 0 gesetzt wird? Damit also fprintf keinen Müll in die Datei schreibt?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
16.07.2008, 16:59 Uhr
kronos
Quotenfisch
(Operator)



Zitat von banshee:
1) Warum wird p_text mit new/delete angelegt? Hat das irgendwelche Vorteile gegenüber dem ganz normalen char* p_text[16384] ?

Die Array-Größe auf dem Stack ist je nach Betriebsystem begrenzt, mit 16k hat man gute Chance über der Grenze zu liegen, daher dynamische allozierung auf dem Heap.


Zitat:
2) Sehe ich das richtig, dass p_text[0] für den Fall dass keine Argumente in der Parameterliste sind, auf 0 gesetzt wird? Damit also fprintf keinen Müll in die Datei schreibt?

Hm, evtl. schreibt sprintf bei ungültigen Parametern gar nichts. Jedenfalls könnte man sicher auch direkt mit vfprintf (ohne Array) arbeiten.
--
main($)??<-$<='?'>>2?main($-!!putchar(
(("$;99M?GD??(??/x0d??/a:???;a"+'?'/4)
??($??)+'?'/3-2-1+$%2)??''?')):'?';??>
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
16.07.2008, 17:25 Uhr
0xdeadbeef
Gott
(Operator)


Mir ist bisher noch kein Betriebssystem untergekommen, dass die Arraygröße auf dem Stack begrenzt hätte, wenn der Stackframe noch erweitert werden kann. Mir ist auch nicht klar, wie das Betriebssystem das unterscheiden sollte.

Meine Vermutung ist, dass hier ursprünglich mal geplant war, eine dynamische Länge einzuführen, das aber später vergessen wurde. Oder vielleicht auch einfach mangelnde Erfahrung, das würde sich mit der merkwürdigen Mischung aus C und C++, dem möglichen Buffer-Overflow und der Verschwendung von Dateideskriptoren decken.

C-Code vorausgesetzt würde ich folgende Änderungen einbauen:

C++:
void printfLog(const char* p_format, ...)
{
    char p_text[16384];
    p_text[0] = 0;
    va_list vaList;

    va_start(vaList, p_format);
    vsnprintf(p_text, sizeof(p_text), p_format, vaList);
    va_end(vaList);

    FILE* p_file = fopen("log.txt", "at");
    fprintf(p_file, "%s", p_text);
    fclose(p_file); // unbedingt notwendig!!

    // delete[] entfernt, p_text ist jetzt auf dem Stack
}


So oder so erscheint mir das System hinter dieser Logging-Datei als nicht besonders sinnvoll. Die Log-Datei wird bei jedem Eintrag neu geöffnet und geschlossen (naja, sie sollte geschlossen werden, sonst wird's noch schlimmer), sie ist fest im Programm verdrahtet...das ist unflexibel und langsam. Sinnvolle Ansätze zum Logging gibt es mehrere, welcher der beste für den use case ist, kann ich ohne nähere Info über das Programm nicht sicher sagen (Denkbar wäre, std::clog zu Beginn auf eine Datei deiner Wahl umzuleiten), aber diese Geschichte hier ist merkwürdig und kaputt und falsch.

Nachtrag:

Im Übrigen wäre es wohl einfacher, vfprintf zu benutzen:

C++:
void printfLog(const char* p_format, ...)
{
    FILE* p_file = fopen("log.txt", "at");
    va_list vaList;
    va_start(vaList, p_format);

    vfprintf(p_file, p_format, vaList);

    va_end(vaList);
    fclose(p_file);
}


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 16.07.2008 um 17:27 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
16.07.2008, 23:28 Uhr
banshee




Zitat von kronos:
Hm, evtl. schreibt sprintf bei ungültigen Parametern gar nichts. Jedenfalls könnte man sicher auch direkt mit vfprintf (ohne Array) arbeiten.


Ja genau das mein ich. Noch nichtmal unbedingt, dass es ungültige Parameter sind, sondern von mir aus auch einfach ein leerer string als Format. Ohne diese Anweisung würde ja dann irgendein Speichermüll ins logfile geschrieben.

@deadbeef: Das fclose() hab ich aus versehen beim kopieren vergessen, das war noch dabei

Woher kriegt man denn dieses ganze Wissen darüber, wann Code effizient ist und wann nicht? Ich studiere jetzt im 4. Semester Informatik, wir benutzen regelmäßig andere Sprachen und irgendwie ist es jedem egal wie der Code aussieht und was er tut, solange er tut, was er soll.
Gibts da gute Literatur zu oder lernt man das dann nur im Job?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
17.07.2008, 01:05 Uhr
0xdeadbeef
Gott
(Operator)


Einfache Antwort: Je weniger der Code zu tun hat, desto schneller ist er tendenziell.

Komplexe Antwort:

Es gibt nen Haufen praktischer Dinge, die man im Studium nicht lernt, dazu zählt das "magische Auge". An der Universität neigen die Leute dazu, sehr theoretisch zu denken, ein bisschen wie Mathematiker halt. "Grob so geht's, der Rest ist trivial und wird sich schon finden." Für eine Lehranstalt ist das auch gar kein so schlechter Ansatz - die Theorie ist verdammt wichtig - aber Programmierung ist irgendwo eben auch ein Handwerk. Wenn du aus der Uni kommst, wurde dir das Fundament beigebracht, das du brauchst, um ein guter Programmierer zu werden, aber die erste Zeit danach wirst du trotzdem langsamen, schwerfälligen, aufgeblasenen und scheinbar funktionierenden, aber trotzdem kaputten Code schreiben - weil du halt nie mittelgroße Projekte in den Sand gesetzt und daran gesehen hast, wie sich Projekte in den Sand setzen. Auch, weil du die ganzen Tools nicht kennst, die einen bei der Analyse helfen können, und - sehen wir den Fakten ins Gesicht - man lernt im Studium zwar über Unit-Tests, aber schreiben tut man sie doch nicht, bis der Chef es verlangt. Nachdem es zum ersten mal verlangt wurde, tut man es freiwillig wieder, aber davor...

Worum es hier geht, ist im Grunde praktische Erfahrung. Das Problem mit praktischer Erfahrung ist, dass man sie nicht aus Büchern lernen kann. Was du willst sind 1. Projekte und 2. Programmierer, mit denen du dich kurzschließen kannst. Sehr hilfreich wäre hier z.B. ein Job in einer kleinen Firma während der Semesterferien oder etwas Vergleichbares. Wenn das nicht geht, schreib zunächst kleinere, dann größere Projekte in deiner Freizeit, und hab ein kritisches Auge darauf, wo du Probleme hast / dir das Design nicht so richtig gefällt, und komm hierher oder in ein Forum oder einen IRC-Kanal deiner Wahl und befrag andere Leute dazu, was sie davon halten.

Für den Moment kann ich dir nahelegen, dich mit den gängigen Debug-Tools vertraut zu machen (z.B. gdb, valgrind, gprof) und immer das KISS-Prinzip im Hinterkopf zu haben; ansonsten wirst du da das meiste aus deinen eigenen Fehlern lernen müssen. Und scheu dich nicht, eigenen Code hier zu zeigen und Verständnisfragen zu fragen, wir helfen gerne - sofern du uns nicht einfach deine Hausaufgaben auftischst, jedenfalls.

Nachtrag: In aller Regel deutlich kritischer als Performance ist Sicherheit. Zum Beispiel der potentielle Buffer-Overflow im obrigen Code - je nach Kontext kann sowas zu Einfalltoren für allerlei Schadsoftware werden.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 17.07.2008 um 01:10 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
17.07.2008, 14:36 Uhr
banshee



wow, danke schonmal für die umfassende Antwort. Ist genau das, was ich erwartet/befürchtet habe

Ich bin eigentlich auch an einer recht renommierten Uni, was Informatik angeht, eingeschrieben und ich denke und hoffe, dass sich da in den nächsten Semestern noch was tut. Ich bin ja gerade erst so ziemlich genau zwischen Grundstudium und Spezialisierung und im nächsten Semester steht zb. das Bachelorpraktikum an, bei der wir in kleinen Gruppen auch irgendwas für eine Firma programmieren müssen. Wie ernsthaft der Job ist, weiß ich nicht (dass Firmen irgendwie wichtige Jobs an Studenten im Grundstudium auslagern, kann ich mir eher weniger vorstellen ^^) aber es ist ja schonmal ein Anfang.
Wir wurden bisher eigentlich auch ganz gut mit praktischen Aufgaben unterstützt, wobei man auch gequält sagen kann, aber das war auf jeden Fall schonmal eine wichtige Erfahrung.
Trotzdem kriegen wir hier teilweise in den Aufgabentemplates code vorgelegt, wo sich selbst mir als sagen wir mal Fortgeschrittenem schon die Fußnägel hochrollen.

Ansonsten werde ich natürlich weiterhin versuchen, so gut wie möglich mein magisches Auge zu schulen und dann mal sehen, was dabei rauskommt
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: