strftime mit new



  • Ich weiß man soll keine ungekapselten News benutzen, aber abgesehen davon, ist das so leak sicher ?

    int test = 5;
    
    while ( strftime (buffer,test,"Now it's %I:%M%p.",timeinfo) == 0){
    
    	std::cout << "err\n";
    	delete[] buffer;
    
    	test+= 5;
    	buffer = new char[test];
    }
    


  • Ja, das "leakt" sicher.



  • Warum? Wie dann verbessern?



  • unsure schrieb:

    Warum?

    .. weil nicht sicher ist, dass 'buffer' nach diesen Zeilen Code freigegeben wird.

    unsure schrieb:

    Wie dann verbessern?

    z.B. so:

    ostringstream buffer;
        buffer << std::put_time( timeinfo, "Now it's %I:%M%p." );   // erfordert #include <iomanip>
        cout << "buffer enthaelt: [" << buffer.str() << "]" << endl;
    

  • Mod

    unsure schrieb:

    Warum?

    1. Weil es all die typischen Fehler hat, die rohe Pointer immer haben. Das heißt vor allem, dass es bei Exceptions leckt.
    2. Der Code leckt doch ganz direkt, sobald die Schleife endet.

    Wie dann verbessern?

    -Wenn schon new, dann mit Smartpointern.
    -Wenn schon dynamischer Speicher, dann gleich vector/string (oder anderen geeigneten Container, aber hier ist string am passendsten).
    -Wenn du die Zeit ausgeben willst, wäre put_time die C++'ige Lösung.

    edit: Zu langsam.



  • 2. Der Code leckt doch ganz direkt, sobald die Schleife endet.

    Ja sorry, das hab ich nicht mehr gepostet, nach der Schleife wird buffer in nen String kopiert und buffer sofort freigegeben.

    Ja, die Lösung von Werner ist woh das was ich gesucht habe.. put_time.. passt. DAnke.

    @ Sepp..... Wie würde ich dann die new usw . mit smart poitnern erstezen ? Hab mich damit noch nicht so befasst, nur kurze info... ?



  • http://en.cppreference.com/w/cpp/memory/unique_ptr

    Etc. pp. Findest du alles in entsprechenden Dokus. Du verwaltest selber keine rohen, besitzenden pointer sondern lässt es für dich machen.



  • Du kannst auch direkt in einen std::string schreiben:

    #include <string>
    #include <ctime>
    
    int main()
    {
       std::string Buffer( 5 );
       while( std::strftime( &Buffer[0], Buffer.size(), "Now it's %I:%M%p.",timeinfo ) == 0)
       {
          Buffer.resize( Buffer.size() * 2 );
       }
       // voila... Buffer ist gefüllt
    }
    

    Code ist ungetestet.



  • unsure schrieb:

    Wie würde ich dann die new usw . mit smart poitnern erstezen ? Hab mich damit noch nicht so befasst, nur kurze info... ?

    So etwa:

    std::unique_ptr< char[] > buffer;   // erfordert #include <memory>
        for( size_t test = 5; buffer.reset( new char[test] ),
                strftime( buffer.get(), test, "Now it's %I:%M%p.", timeinfo ) == 0; test += 5 )
            std::cout << "err\n";
    
        std::cout << "Buffer enthaelt: [" << buffer.get() << "]" << std::endl;
    


  • Danke an alle, ist jetzt klar.



  • std::string Buffer( 5 );
    

    Das wird nicht klappen


  • Mod

    nope___ schrieb:

    std::string Buffer( 5 );
    

    Das wird nicht klappen

    Dann gib doch auch an, wie es richtig geht: std::string Buffer( 5, ' ' );

    Wobei man noch betonen sollte, dass die Lösung mit dem Smartpointer hier nicht gut ist! Das wurde nur erwähnt, weil der Threadersteller ungekapseltes new benutzt hat. Direkt std::string zu nutzen ist hier die Lösung, das ist schließlich ein noch viel smarterer Container.

    Und vielleicht lieber std::put_time (falls vorhanden), was im Prinzip auch nichts groß anderes ist als ein Wrapper um das, was der Threadersteller hier versucht. Aber vermutlich etwas geschickter implementiert.


Anmelden zum Antworten