sprintf, auto. Speicherallokierung?



  • Hmm, also mal ne blöde Frage:
    Irgendwo her müssen die Daten ja kommen, ich denke mal eine Datei.
    Wäre es nicht am besten hier einfach beim Einlesen (das man ja normalerweise in einer Schleife macht) den Speicher dynamisch zu allokieren? Also erstmal (keine Ahnung wieviel Daten Du da so hast) 1024 kbyte allokieren (malloc, new whatever) und dann dynamisch zu erweitern.
    Ganz vereinfacht dargestellt:

    while (dateilesen)
    wenn lesebuffer zu klein:
    kopiere lesebuffer nach tmp, reallokiere lesebuffer , kopiere temp nach lesebuffer

    Das wäre immer noch sauberer als einfach mal 10MB zu reservieren ;). Und ich denke mit 1MB Speicher tust du niemand weh, wenn du das einfach anlegst. Oder hab ich was missverstanden?
    rya.



  • Ne also es geht um ne Loggingfunktion. D.h. während dem Lauf wird eben bei einem bestimmten fehler

    error( msg, ... );

    aufgerufen.

    Und dessen Größe muss dann eben berechnet werden um anschließend in eine Datei geschrieben werden zu können.



  • So ich denke ich werde nun wirklich die Lösung nehmen, die Puffergröße um Zweierpotenzen so lange zu erhöhen bis alles reinpasst, per snprintf().

    Anschließend kann ich die echte Stringlenge ja auslesen und auf die benötigte Größe verkleinern.

    Außer ihr habt doch noch eine bessere Möglichtkeit parat 😉

    danke auf jeden Fall!

    tremml



  • nein mach snprintf(NULL, 0, "Formatstring", ...) dann kriegste die größe



  • Sicher dass das in C++ funktioniert und portabel ist?
    @tremml: wenn du z.B. mit einem statischen 4k Puffer anfängst wirst du kaum jemals nen grösseren anfordern müssen.
    Ich würde das auf jeden Fall so machen, damit hast du in wahrscheinlich 99% aller Fälle den Puffer "gratis", also ohne new/delete, und musst auch nur 1x sprintf aufrufen.

    Mal davon abgesehen dass ich wohl eher nen stream zum loggen verwenden würde... 🙂



  • Nö, natürlich ist das weder portabel noch funktioniert es auf irgendeiner der mir zur Verfügung stehenden Plattformen (hätte mich aber auch sehr gewundert).

    @tremml:
    Nach C99 ("Strich" erwähnte es schon) kann man da mit snprintf was basteln, das gibt nämlich die tatsächlich benötigte Länge zurück, auch wenn der Puffer zu klein war. Damit hast Du maximal zwei Aufrufe, da Du beim ersten Fehlversuch die Länge kennst.

    GCC bzw. glibc ab 2.1 implementieren das so (auch in C++, da dieselbe Bibliotheksfunktion dahinterliegt), für MSVC hat ja "Strich" eine Emulationsmöglichkeit gepostet.



  • Haha. Auf das leichteste komm ich natürlich wieder nicht.

    Ich will eventuell loops machen um mich an einen Wert ranzutasten der mir gegeben wird 😉

    Danke an Strich für diese Erleuchtung.

    4k großen puffer würde ich nicht empfehlen, weil der zwar fast nie voll werden wird, aber ihr kennt wohl morphy noch nicht 😉

    Und das mit dem Stream hab ich wohl nicht ganz verstanden. Ich mein in einen (File-)Stream kommt ja der gesamte String. Aber erstmal muss er so aussehen wie er aussehen soll. Und dass ich den Benutzerstring zerlege und nacheinander in einen Mem-String packe seh ich auch nicht als sinnvoll. Oder gibts da (der interesse halber) andere Dinge?

    Ich werde auf jeden Fall den Weg mit dem snprintf gehen, was ich auch schon gemacht habe - nur dass ich mich eben dummerweise an ein vorhandenes Ergebnis antaste.

    Danke auf jeden Fall für die zahlreiche Hilfe!

    mfg tremml



  • tremml schrieb:

    Ich werde auf jeden Fall den Weg mit dem snprintf gehen, was ich auch schon gemacht habe - nur dass ich mich eben dummerweise an ein vorhandenes Ergebnis antaste.

    Ich würde das Ergebnis prüfen. Ist das >= der zur Verfügung stehenden Länge, hast Du eine C99-konforme Implementierung und kannst die zurückgegebene Länge sofort nutzen, kommt -1 zurück, musst Du Dich herantasten.



  • ist alles schon geschehen, ich bekomme genau die Anzahl der zu schreibenden Zeichen (ohne 0-Byte).

    Oder sollte ich eventuell so eine Prüfung zur Laufzeit implementieren, dass das auch auf älteren Systemen funktioniert ..... ich denke ja. Danke auf jeden Fall



  • @tremml: du solltest schon richtig lesen bevor du mit murphy vor den latz knallst.
    Du sollst einen 4K Puffer AM STACK anlegen, und es erstmal damit probieren. Da du ja snprintf verwendest bekommst du eh raus wenn der Puffer zu klein war. Und IN DEM FALL gehst du dann her und versuchst (wie auch immer - Schleife oder Returnwert von snprintf) die Grösse zu ermitteln, und allozierst dann einen entsprechend grossen Puffer dynamisch.

    Was die Streams angeht: ich meine C++ Streams im Interface, also ganz auf printf verzichten.



  • Okay, tut ma Leid. Hab ich wohl überlesen 😉

    Mit dem Interface hast du Recht, aber für mich wird da der Aufruf zu klobig, weshalb ich lieber dabei bleibe.



  • hahahaha


Anmelden zum Antworten