Dynamischen Speicher anfordern



  • Hi
    Ich arbeite immer noch an meiner HTTP Bibliothek und habe noch mal eine frage. Ich möchte dem Benutzer die Möglichkeit geben den Content entweder in eine Datei oder direkt in den Arbeitsspeicher zu speichern. Nun habe ich erstmal einen std::vector<char> genommen aber damit bin ich nicht zufrieden, da ich ein char* brauche um die daten mit gzip oder deflate zu dekomprimieren. Kann mir vielleicht einer einen Tip geben wie ich das direkt speichern kann ohne das ich vorher weiß wie groß der Content ist?

    MfG cobra11freak



  • Dynamisch allozieren geht mit new/new[].



  • Was spricht gegen folgendes:

    std::vector<char> data;
    
    char * p = &data[0];
    
    //p zeigt jetzt auf die Daten die in data liegen.
    


  • Vielen Dank rean :)!

    Immer diese verdammten pointer ich verstehe sie einfach nicht. Aber euer Artikel im Magazin hat mir zumindestens etwas mehr Licht im dunklem verschafft.

    char* c_str()
        {
            return &data[0];
        }
    

    MfG cobra11freak



  • Es gibt da auf jeden Fall noch etwas, auf das du achten musst: Der Vektor darf nicht leer sein, sonst erzeugst du mit dem Zugriff auf das erste Element eine Zugriffsverletzung:

    char* c_str()
    {
      if( false == data.empty() )
      {
         return &data[0];
      }
      return 0;
    }
    


  • DocShoe schrieb:

    char* c_str()
    {
      if( false == data.empty() )
      {
         return &data[0];
      }
      return 0;
    }
    

    Ihgitt... empty liefert doch schon einen boolschen Wert, den brauchst nicht mit false vergleichen.

    =>

    char* c_str()
    {
      if( !data.empty() )
      {
         return &data[0];
      }
      return 0;
    }
    

    Und wenn man dann noch so vorgeht dass man für den "nicht richtig"-Fall den early-return macht statt für den "alles ok"-Fall (ist einfach üblicher), dreht man das Ganze noch um:

    char* c_str()
    {
      if( data.empty() )
      {
         return 0;
      }
    
      return &data[0];
    }
    


  • pumuckl schrieb:

    DocShoe schrieb:

    char* c_str()
    {
      if( false == data.empty() )
      {
         return &data[0];
      }
      return 0;
    }
    

    Ihgitt... empty liefert doch schon einen boolschen Wert, den brauchst nicht mit false vergleichen.

    Tjo, gibt halt schon eigenartige Richtlinien... hab mich inzwischen so dran gewöhnt, dass ich sie auch privat einsetze. Ich weiss, welche Ausdrücke bool´sch sind oder welche implizit nach bool konvertierbar sind.



  • DocShoe schrieb:

    Tjo, gibt halt schon eigenartige Richtlinien... hab mich inzwischen so dran gewöhnt, dass ich sie auch privat einsetze. Ich weiss, welche Ausdrücke bool´sch sind oder welche implizit nach bool konvertierbar sind.

    sag mal kurz eine situation wo
    false==v.empty()
    geht aber
    !v.empty()
    nicht.

    wenn wir von programmierfehlern in v mal absehen.



  • Es geht nicht darum, ob wann was wie geht, sondern es gibt eine Richtlinie, die explizite Vergleiche vorschreibt. Über Sinn oder Unsinn braucht man sich nicht zu streiten, das sehe ich wohl genauso wie ihr.



  • // ich mach's immer in so einer combination, oder ein struct eben...
    char* data; // pointer auf 'data' vereinbaren (nur ein pointer, der auf irgendetwas zufälliges zeigt
    size_t data_size = 0; // größe in bytes
    
    size = 100; // neue größe festlegen
    data = new char[size]; // neuen speicher anfordern, und Zeiger 'data' auf den beginnenden byte des allokierten speichers setzen
    
    for (int i=0; i<size; i++) // daten füllen
    { data[i] = i*2-100; }
    
    for (int i=0; i<size; i++) // daten ausgeben
    { cout << std::hex << data[i] << " "; }
    


  • @lk: Warum nicht so:

    std::vector<char> data;
    data.resize(100);
    
    for(int i=0, size=data.size(); i<size; ++i)
        data[i] = i*2-100;
    
    for(int i=0, size=data.size(); i<size; ++i)
        std::cout << std::hex << data[i] << " ";
    

  • Administrator

    lk schrieb:

    // ich mach's immer in so einer combination, oder ein struct eben...
    char* data; // pointer auf 'data' vereinbaren (nur ein pointer, der auf irgendetwas zufälliges zeigt
    size_t data_size = 0; // größe in bytes
    
    size = 100; // neue größe festlegen
    data = new char[size]; // neuen speicher anfordern, und Zeiger 'data' auf den beginnenden byte des allokierten speichers setzen
    
    for (int i=0; i<size; i++) // daten füllen
    { data[i] = i*2-100; }
    
    for (int i=0; i<size; i++) // daten ausgeben
    { cout << std::hex << data[i] << " "; }
    

    Und wieso verzichtest du hier freiwillig auf so Dinge wie RAII? Auch hast du im gezeigten Code bereits ein Speicherleck, weil ein delete[] data; fehlt. Genau solche Fehler können einem mit std::vector nicht passieren, da der Speicher für einem verwaltet wird. Man bekommt dadurch auch Dinge wie Excpetionsicherheit. Richtlinie: std::vector unbedingt einem rohen Zeiger/Array vorziehen.

    Grüssli



  • Ich habe festgestellt, das der Zugriff über den Index Operator wesentlich länger braucht als ein pointer auf data und dann mit cout raushauen.



  • cobra11freak schrieb:

    Ich habe festgestellt, das der Zugriff über den Index Operator wesentlich länger braucht als ein pointer auf data und dann mit cout raushauen.

    Um sowas festzustellen, solltest du in den Release-Modus, alle Optimierungen aktivieren und alle Sicherheits-Checks und Debug-Laufzeitumgebungen deaktivieren. Und vielleicht auch mehrmals testen. Dann können wir nochmals schauen, was schneller ist.

    Davon abgesehen: Hast du lieber ein schnelles verbuggtes oder ein minimal langsameres, aber korrektes Programm?



  • Nexus schrieb:

    cobra11freak schrieb:

    Ich habe festgestellt, das der Zugriff über den Index Operator wesentlich länger braucht als ein pointer auf data und dann mit cout raushauen.

    Um sowas festzustellen, solltest du in den Release-Modus, alle Optimierungen aktivieren und alle Sicherheits-Checks und Debug-Laufzeitumgebungen deaktivieren. Und vielleicht auch mehrmals testen. Dann können wir nochmals schauen, was schneller ist.

    Davon abgesehen: Hast du lieber ein schnelles verbuggtes oder ein minimal langsameres, aber korrektes Programm?

    Mag sein das es nicht am [] Operator liegt aber dafür an cout , je häufiger du cout Aufrufst,desto langsamer wird es. Den geschwindigskeits Unterschied kann man sogar mit seinen Augen sehen.



  • cobra11freak schrieb:

    Mag sein das es nicht am [] Operator liegt aber dafür an cout , je häufiger du cout Aufrufst,desto langsamer wird es. Den geschwindigskeits Unterschied kann man sogar mit seinen Augen sehen.

    Jede Ausgabe ist langsam, und je nach dem welchen Compiler du verwendest, mag es an der Implementierung liegen.

    Unter Microsoft (getestet unter 2008) ist der Vector mit Ausnahme der Allokation identisch schnell wie ein C-Array, sofern du im Releasemodus linkst und folgendes im Code stehen hast:

    #define _SECURE_SCL 0
    

    Was unter MSVC noch ein Problem ist, ist das der Ausgabestream keinen Buffer zugeordnet bekommen hat. Wenn man dies ändert, war die Ausgabe deutlich schneller... Leider finde ich gerade nicht den Forumsthread wieder (Wenn ich ihn doch finde, werde ich ihn nachreichen).

    // Nachtrag: Probier mal folgendes am Programmanfang...
    char buf[1024];
    setvbuf(stdout, buf, _IOLBF, 1024);
    

  • Administrator

    asc schrieb:

    // Nachtrag: Probier mal folgendes am Programmanfang...
    char buf[1024];
    setvbuf(stdout, buf, _IOLBF, 1024);
    

    Wird wohl nicht viel bringen. stdout ist auf MSVC bereits gepuffert, soweit mir bekannt ist. Es geht somit nur um den streambuf von std::cout . Die Pufferung geschieht wie folgt:

    #include <iostream>
    
    int main()
    {
      int const consoleOutBufferSize = 512;
      char consoleOutBuffer[consoleOutBufferSize];
      std::cout.rdbuf()->pubsetbuf(consoleOutBuffer, consoleOutBufferSize);
    
      // ...
    }
    

    http://www.cplusplus.com/reference/iostream/streambuf/pubsetbuf/

    Dies wird die Sache deutlich beschleunigen. Danach ist kein Unterschied mehr zwischen printf und std::cout zu messen.

    Grüssli



  • cobra11freak schrieb:

    ...Mag sein das es nicht am [] Operator liegt aber dafür an cout...

    Das hat aber nichts mit der Frage "Warum nicht std::vector?" zu tun, um die es hier geht.

    Gruß,

    Simon2.



  • Dravere schrieb:

    Wird wohl nicht viel bringen. stdout ist auf MSVC bereits gepuffert, soweit mir bekannt ist. Es geht somit nur um den streambuf von std::cout ...

    Danke, hatte wie gesagt nicht den Thread gefunden in dem es erwähnt wurde. Genau das meinte ich ursprünglich, hatte beim googlen aber nur das andere gefunden...


Log in to reply