null in std::string -> UB oder OK?



  • Nö, selbst wenn das gehen würde, würde sich die Seuche dann ja auch in den Rest des Programms ausbreiten, weil ich mit char* hantieren müsste.

    Nein, so habe ich das nicht gemeint.

    Du kannst im ganzen Programm ganz normal mit dem std::string arbeiten ohne dieses gefrickel mit dem anhängen einer '\0'.

    Dann must Du nur genau dort wo ein NULL terminierter string verlangt wird den std::string.c_str() verwenden. Das ist übrigends keine Seuche 😉 die meisten API's verwenden const char* oder char* und genau zu diesem Zweck hat std::string die Funktion c_str()



  • Mal ganz banal:

    #include <string>
    #include <iostream>
    
    std::string frame(const std::string& s)
    {
    	return std::string("start") + s + "ende";
    }
    
    std::string generateNormal()
    {
    	return "huhu";
    }
    
    std::string generateFrickelMist()
    {
    	std::string s("003bla_");
    	s.back() = '\0';
    	return s;
    }
    
    std::string generate()
    {
    	bool cond( false );
    	auto s = cond ? generateNormal() : generateFrickelMist();
        return frame(s);
    }
    
    void send(const std::string& s)
    {
        // Druecks ins Socket.
    	std::cout << s << "\n";
    }
    
    int main()
    {
        for(;;)
        {
            auto s = generate();
            send( s );
        }
    }
    

    Wie wär das jetzt mit std::string.c_str() schöner?



  • Nee, wird nicht schöner 😉

    Ich bin davon ausgegangen, dass Du eine struct für einen API Aufruf ausfüllen musst.



  • Arcoth schrieb:

    Es ist nicht definiert, dass s.c_str() == &s[0] .

    Doch.

    (Ja, in C++03 ist es nicht explizit definiert, aber de facto eben doch)



  • Die C++-Programmiersprache §20.3.7 schrieb:

    [...]im von c_str() oder data() reservierten Puffer[...]


  • Mod

    c++11 schrieb:

    Doch.

    Ja, das stimmt, seit C++11:

    const charT* c_str() const noexcept;
    const charT* data() const noexcept;
    

    Returns: A pointer p such that p + i == &operator[](i) for each i in [0,size()] .

    In C++03 war das zwar in den Implementierungen praktisch immer der Fall, war aber nicht garantiert.


  • Mod

    §20.3.7

    So einen Paragraphen gibt es nicht 😕 21.3.7 genauso wenig.



  • Hallo Doby,

    std::string generateFrickelMist() 
    { 
         std::string s("003bla_"); 
         s.back() = '\0'; 
         return s; 
    }
    

    könntest Du auch so machen:

    std::string generateFrickelMist() 
    { 
         std::string s("003bla"); 
         s.push_back('\0'); 
         return s; 
    }
    


  • Oh stimmt, das ist hübscher, danke.



  • Arcoth schrieb:

    §20.3.7

    So einen Paragraphen gibt es nicht 😕 21.3.7 genauso wenig.

    Die C++-Programmiersprache §20.3.7


  • Mod

    Whups! Ich habe gar nicht geschaut, auf was sich das bezieht 🙂


Anmelden zum Antworten