memset in C++



  • Gibt es unter C++ eine Alternative zu memset oder kann man es verwenden? Mein Ziel ist es ein Array aus unsigned chars so schnell wie möglich auf 0 zu setzen.

    G hibbes



  • Natürlich kannst du man: memset einfach verwenden. Ansonsten gibt es noch std::fill.



  • Dankeschön 🙂



  • hibbes schrieb:

    Mein Ziel ist es ein Array aus unsigned chars so schnell wie möglich auf 0 zu setzen.

    In welchem Kontext?

    unsigned char arr[X] = {};
    //bzw.
    std::tr1::array<unsigned char, X> arr;
    

    oder

    std::vector<unsigned char> arr(X);
    

    je nachdem gibt es eben verschiedene Methoden.
    wieso willst du es überhaupt komplett auf 0 setzen? ist das nötig? meist ist es sinnvoller, die länge mitzuspeichern(dann kann z.bsp. auch eine 0 drin vorkommen, ohne das der nutzer dann meint, das wäre schon das eof-kennzeichen)

    bb



  • Ich habe mal einen virtuellen Framebuffer in C geschrieben und wollte die Funktionen dazu jetzt mit meinen noch sehr bescheidenen C++ Kenntnissen in eine Klasse umwandeln. Die Funktion zum löschen des Framebuffer war in C folgende:

    typedef struct
    {
      int x_res;
      int y_res;
      int bytes_per_pixel;
      int size;
      unsigned char *data;
    }Framebuffer;
    
    Framebuffer *fb;
    
    fb->x_res = 320;
    fb->y_res = 256;
    fb->bytes_per_pixel = 3;
    fb->size = fb->x_res * fb->y_res * fb->bytes_per_pixel;
    fb->data = calloc(fb->size, sizeof(fb->data));
    
    void fb_clear(Framebuffer *fb)
    {  
      memset(fb->data, 0, fb->size);
    }
    

    Bei der Umsetzung habe ich auch erstmal wieder ein CArray genommen, wäre da ein Vector für C++ "besser"?

    G hibbes



  • hibbes schrieb:

    typedef struct
    {
      int x_res;
      int y_res;
      int bytes_per_pixel;
      int size;
      unsigned char *data;
    }Framebuffer;
    
    Framebuffer *fb;
    
    fb->x_res = 320;
    fb->y_res = 256;
    

    fb wurde nicht initialisiert.

    hibbes schrieb:

    Bei der Umsetzung habe ich auch erstmal wieder ein CArray genommen, wäre da ein Vector für C++ "besser"?

    kommt drauf an, was du mit "besser" meinst. Nach meinem Verständnis ist

    class FrameBuffer
    {
      int x_res;
      int y_res;
      int bytes_per_pixel;
      vector<unsigned char> data;
    public:
      ...
    };
    

    schon praktisch, da man so kein new/delete/malloc/calloc/free sowie einen eigenen Kopierkonstruktor, Zuweisungsoperator und Destruktor benötigt, aber trotzdem das FrameBuffer-Objekt (bzw der Vektor) sich für den reservierten Speicher verantwortlich fühlt. In Deinem Fall ist das nicht so. Du merkst Dir einfach einen Zeiger in der Struktur und wer wo was damit macht (Speicher reservieren und freigeben), bleibt offen. Du hältst Dich also nicht an das RAII-Prinzip.

    kk



  • Danke für die Hinweise, das C-Beispiel habe ich für hier extra zusammengeschipselt.
    Kann man denn in reinem C RAII nutzen? In meiner neuen C++ Klasse habe ich per new im Konstuktor Speicher reserviert und im Destruktor mit delete[] wieder freigegeben, das ist doch RAII oder?

    Ein Vektor ist dann wohl doch eleganter.

    G hibbes



  • hibbes schrieb:

    Danke für die Hinweise, das C-Beispiel habe ich für hier extra zusammengeschipselt.
    Kann man denn in reinem C RAII nutzen? In meiner neuen C++ Klasse habe ich per new im Konstuktor Speicher reserviert und im Destruktor mit delete[] wieder freigegeben, das ist doch RAII oder?

    Ein Vektor ist dann wohl doch eleganter.

    G hibbes

    Wenn du in C programmierst, dann kannst du keine Klassen verwenden und hast auch keine Desktrutoren. Folglich kannst du RAII nicht nutzen.

    Ja, das ist soweit RAII, wenn du im Konstruktor alles bereitstellst und im Destruktor alles aufräumst. Praktisch solltest du aber noch den Zuweisungsoperator und Kopierkonstruktor einbeziehen.

    http://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)



  • unskilled schrieb:

    hibbes schrieb:

    Mein Ziel ist es ein Array aus unsigned chars so schnell wie möglich auf 0 zu setzen.

    In welchem Kontext?

    unsigned char arr[X] = {};
    //bzw.
    std::tr1::array<unsigned char, X> arr;
    

    oder

    std::vector<unsigned char> arr(X);
    

    je nachdem gibt es eben verschiedene Methoden.

    std::fill kann man immer verwenden.

    für "nackte" arrays kann man sich auch "schöne" hilfs-makros machen

    #define ARRAY_SIZE(a) ((sizeof(a))/(sizeof((a)[0])))
    #define ARRAY_BEGIN(a) (&((a)[0]))
    #define ARRAY_END(a) (ARRAY_BEGIN(a) + ARRAY_SIZE(a))
    
    void foo()
    {
        int a[100];
        std::fill(ARRAY_BEGIN(a), ARRAY_END(a), 0);
    }
    


  • hustbaer schrieb:

    für "nackte" arrays kann man sich auch "schöne" hilfs-makros machen

    #define ARRAY_SIZE(a) ((sizeof(a))/(sizeof((a)[0])))
    #define ARRAY_BEGIN(a) (&((a)[0]))
    #define ARRAY_END(a) (ARRAY_BEGIN(a) + ARRAY_SIZE(a))
    
    void foo()
    {
        int a[100];
        std::fill(ARRAY_BEGIN(a), ARRAY_END(a), 0);
    }
    
    template<typename T*,size_t size>
    size_t size(T(&arr)[size]){
      return size;
    }
    template<typename T*,size_t size>
    size_t begin(T(&arr)[size]){
      return arr;
    }
    template<typename T*,size_t size>
    size_t end(T(&arr)[size]){
      return arr+size;
    }
    //und noch mit const
    


  • Dankeschön, das muss ich erstmal bei ner Runde Starcraft II verdauen. 😃



  • @ volkard:
    Dein Vorschlag ist zwar typsicher, aber nicht mehr compilezeit-konstant (für die Grösse könnte das vielleicht manchmal notwendig sein). Vielleicht aber in C++0x mit constexpr .

    Ich würde jedoch ohnehin gleich std::tr1::array benutzen, dann hat man auch ein STL-kompatibles Interface und nebenbei noch schöne Index- und Iteratorprüfungen im Debug-Modus.

    std::tr1::array<int, 100> a;
    std::fill(a.begin(), a.end(), 0);
    

    In diesem speziellen Falle ginge auch:

    std::tr1::array<int, 100> a = {};
    


  • Also ARRAY_SIZE würde ich immer als Makro anbieten (zumindest zusätzlich), genau wegen dem was Nexus schon erwähnt hat (Template nicht compile-time konstant).
    Mit C++0x wird sich das ändern, aber bis dahin...

    Bei begin()/end() kann man vermutlich auch gut ohne compile-time konstant auskommen.

    BTW: template<typename T*, size_t size> - also der * geht da IMO gar nicht 🙂 vertippt?



  • hustbaer schrieb:

    BTW: template<typename T*, size_t size> - also der * geht da IMO gar nicht 🙂 vertippt?

    Die letzten Tage stand nach T oft ein *. Da haben meine bösen Fingerchen das da automatisch getippt, ohne daß ich es mitgekriegt habe.



  • hustbaer schrieb:

    std::fill kann man immer verwenden.

    Dem wollte ich nicht widersprechen - nur denke ich noch immer, dass es unnötig ist...

    bb



  • Danke Danke bitte schließt den Fred, ich wollte doch nur ein Array mit 0 füllen 😃 Ihr seit ja wahnsinnig 😃 , was erhalte ich für Antworten wenn ich versuche einen Graphen zu implementieren, eine Diplomarbeit. 😃

    Ne mal im ernst, ich schätze das Forum hier sehr, da es eines der wenigen ist in dem man wirkliche Profis antrifft.

    Großes Lob an euch alle.
    G hibbes


Anmelden zum Antworten