std::stringstream in char*



  • Hallo Leute,

    ich habe eine Funktion, die als Parameter einen Text als 'char*' erwartet. Mein Ausgangsformat ist allerdings ein std:stringstream. Wie stelle ich es am besten an?

    Ich habe jetzt folgendes:

    std::stringstream ss;
    ss << "Mein Ausgangstext" << "noch irgendwas";
    
    char *text = const_cast<char*>(ss.str().c_str());
    meineFunktion(text);
    

    Es funktioniert zwar, allerdings schmeißt mir Valgrind mehrere Fehlermeldungen:
    "Invalid read of size 1 [PID: xxxxx]"

    Ich habe scheinbar irgendwas falsch gemacht. Aber wie mache ich es am besten? Muss ich die Daten erst in eine neue Variable (z.B. std::vector<char>) kopieren und übergeben oder geht es einfacher?

    Gruß,
    SBond



  • Der Stringstream erzeugt einen String, den du aber nur temporär hälst. Und davon nutzt du dann den CStr, der an das String Objekt gekoppelt ist. Der Zeiger den dir c_str() gibt ist so lange nur gültig wie das zugehörige String Objekt lebt (und ich glaube solange der sich intern nicht vergrößern muss und deswegen umkopiert?!). Du nutzt also von einem Temporary den Speicher, der nicht mehr gültig ist.



  • std::stringstream ss;
    ss << "Mein Ausgangstext" << "noch irgendwas";
    
    std::string s = ss.str();
    meineFunktion(&text[0]);
    

    Allerdings fragt sich, was meineFunktion(..) macht.. z. B. ob sie eine 0-Terminierung erwartet, den Speicher beschreibt usw.

    // Edit: Setzt, zumindest theoretisch, C++11 voraus, da erst ab da bei std::string ein zusammenhängender Speicherbereich vorgeschrieben ist.



  • was auch funktioniert ist:

    meineFunktion(const_cast<char*>(ss.str().c_str()))
    

    ... auch wenn es nicht so schön aussieht.

    Ja das Objekt ist natürlich temporär. Daran hätte ich besser vorher mal denken sollen 😞 . Die Version von theta funktioniert natürlich auch 😉

    vielen Dank euch beiden 😃



  • Ich gehe davon aus, dass meineFunktion(..) aus einer API (mit einem Designfehler) stammt, die nicht zu ändern ist und in der Dokumentation steht gross, dass der Inhalt auf den der char* zeigt nicht verändert wird.. oder?

    Ansonsten ist der Ansatz mit dem c_str() und const_cast<..> äusserst fragwürdig.



  • Genau genommen handelt es sich hierbei um eine Funktion aus der OpenSSL-Bibliothek (1.1.0 Beta1):

    X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, int ext_nid, char *value);
    

    Der Parameter 'value' ist hierbei der Null-terminierte Text. Eine Beschreibung gibt es nicht und diese Funktion ist auch nicht in der offiziellen Dokumentation vorhanden. ...was leider bei vielen Funktion der Fall ist -.-


Log in to reply