was ist die beste Möglichkeit einen Datenpuffer aus einer Funktion zurückzugeben??



  • Hallo Leute,

    wie gebt ihr eigentlich Daten aus einer Funktion zurück, wenn wir mal annehmen dass die Größe der Datenmenge nicht bekannt ist?

    Variante 1:

    unsigned char* getBuffer(int &bufSize);
    

    Hier reserviert die Funktion getBuffer dynamischen Speicher und schreibt die Größe in die Variable bufSize. Bei Erfolg wird ein Pointer zurückgegeben und im Fehlerfall ein nullptr. Nachteil ist schon mal, dass ich den Speicher manuell freigeben muss. ...eventuell kann man aber auch einen SmartPointer verwenden (bin mir nicht sicher)

    Variante 2:

    int getBuffer(unsigned char &buffer, int maxBufSize);
    

    Hier schreibt die Funktion die Daten in die gegebene Referenz 'buffer'. maxBufSize stellt dabei die Größe des Puffers dar. Rückgabewert wäre z.B. Die Anzahl der kopierten Bytes

    Variante 3:

    typedef struct {
        unsigned char *buf;
        unsigned int size;
    }data_t;
    
    data_t getBuffer();
    

    Hier werden die Daten einfach in eine struct gepackt.

    Variante 4:

    std::vector<unsigned char> getBuffer();
    

    Wahrscheinlich die beste Methode. Speicher wird automatisch erweitert und man muss sich keine Gedanken um die Freigabe machen.
    Frage: Kann ich einfach einen std::vector zurückgeben oder kann das irgendwelche Probleme verursachen? Was gebe ich im Fehlerfall zurück? Sowas: 'return std::vector<unsigned char>();'?

    ... gibt es noch bessere Varianten? Wie macht ihr es?

    viele Grüße,
    SBond



  • SBond schrieb:

    Variante 4:

    std::vector<unsigned char> getBuffer();
    

    Wahrscheinlich die beste Methode. Speicher wird automatisch erweitert und man muss sich keine Gedanken um die Freigabe machen.
    Frage: Kann ich einfach einen std::vector zurückgeben oder kann das irgendwelche Probleme verursachen?

    Das sieht vernünftig aus, denn: 1) Der Besitzer des Speichers ist eindeutig festgelegt, 2) Speicher wird automatisch freigegeben ⇒ Exception sicher

    SBond schrieb:

    Was gebe ich im Fehlerfall zurück?

    Wirf eine Exception.

    SBond schrieb:

    ... gibt es noch bessere Varianten? Wie macht ihr es?

    Besitzverhältnisse müssen klar (sprich durch den Compiler erzwungen) festgelegt werden. Daher bieten sich hier nur besitzergreifende Container an, wie z.B. vector, unique_ptr, etc.



  • sehr gut 🙂

    kann man eigentlich einen std::vector<unsigned char> irgendwie als Parameter verwenden, in dem eigentlich ein unsigned char* erwartet wird?

    wenn ich z.B. solche Funktionen habe (z.B. aus Bibliotheken):

    int getBuffer(unsigned char *buffer, int maxBufSize);
    


  • Das kommt darauf an, was die Funktion

    int getBuffer(unsigned char *buffer, int maxBufSize);
    

    macht. Was macht sie?



  • SBond schrieb:

    sehr gut 🙂

    kann man eigentlich einen std::vector<unsigned char> irgendwie als Parameter verwenden, in dem eigentlich ein unsigned char* erwartet wird?

    wenn ich z.B. solche Funktionen habe (z.B. aus Bibliotheken):

    int getBuffer(unsigned char *buffer, int maxBufSize);
    

    Wenn sie das macht, was man intuitiv erwartet:

    std::vector<unsigned char> v(100);
    
    auto read = getBuffer(&v[0], v.size() );
    auto read2 = getBuffer(v.data(), v.size() );
    


  • danke 😃

    theta schrieb:

    Das kommt darauf an, was die Funktion

    int getBuffer(unsigned char *buffer, int maxBufSize);
    

    macht. Was macht sie?

    Hätte ich noch erwähnen sollen. Diese Funktion würde jetzt die Daten in den ersten Parameter schreiben. Der zweite Parameter gibt die Funktion die Information, wie groß dieser Speicher ist (damit nicht mehr Daten geschrieben werden, als Speicher reserviert ist). Rückgabewert wäre z.B. die Anzahl der kopierten Bytes


Anmelden zum Antworten