Ist das legal: memcpy mit UDT



  • Hallo.

    Ist folgender Code legales C++ - bzw. gibt es dabei Probleme auf bestimmten PLattformen?

    template<typename T>
    void doit()
    {
      void* p=::operator new(sizeof(T));
      void* p2=::operator new(sizeof(T));
    
      new(p)T();
    
      memcpy(p2, p, sizeof(T));
    
      ::operator delete(p);
    
      //do something with p2
    
      static_cast<T*>(&p2)->~T();
      ::operator delete(p2);
    }
    

    Sprich: ist das memcpy legal?
    T kann jede nur vorstellbare Klasse sein.



  • Ich habe im Standard geschautet. Es sagt das folgendes.
    new T ist equivalent to operator new (sizeof T)
    sizeof T gibt Byte-zahl zurueck.
    (dabei sizeof (char) == 1)
    memcpy (dst, src, n) kopiert n Byte aus src nach dst.
    so es soll kein Problem sein.



  • itman schrieb:

    new T ist equivalent to operator new (sizeof T)

    Na das hoffe ich aber nicht. Schließlich will ich den Ctor selber aufrufen 😉

    Ich weiss, dass das kopieren im Prinzip OK ist - aber ich bin mir nicht sicher ob es irgendwelche Probleme mit virtuelle Methoden/Basisklassen etc. gibt.

    Weil ich nicht weiss, warum keine STL Container bei einem umkopieren ein memcpy machen, sondern echt tiefe Kopien anlegen...



  • Kenn mich da nicht so aus, aber steckt im Speicher auf den p zeigt nicht auch die vtable drin? Die kann man ja nicht einfach so kopieren, weil sie implementationsabhaengig ist.



  • Ich weiss, dass das kopieren im Prinzip OK ist - aber ich bin mir nicht sicher ob es irgendwelche Probleme mit virtuelle Methoden/Basisklassen etc. gibt.

    Natuerlich, kannst du damit Probleme haben (abe sehr unwahrsheinlich). Objekt-kopieren mit memcpy ist nicht portabel.



  • Kenn mich da nicht so aus, aber steckt im Speicher auf den p zeigt nicht auch die vtable drin? Die kann man ja nicht einfach so kopieren, weil sie implementationsabhaengig ist.

    Die vtables sind wohl nicht das Problem, weil die Kopie ja im gleichen Programm gemacht wird.

    Ein Problem kann es zumindest geben, wenn T strings enthält. Die Stringklasse merkt sich die Anzahl der Objekte, die einen String benutzen. Bei einem memcpy wird diese Anzahl nicht erhöht.



  • Geo schrieb:

    Ein Problem kann es zumindest geben, wenn T strings enthält. Die Stringklasse merkt sich die Anzahl der Objekte, die einen String benutzen. Bei einem memcpy wird diese Anzahl nicht erhöht.

    Nein, das ist kein Problem - denn ich erstelle ja keine echte Kopie sondern 'move' den Speicher nur. dh es wird kein Dtor für das alte Objekt aufgerufen.



  • Und wofuer brauchst du dass? Ich glaube dass Man es einfacher machen kann.



  • class Window
    {
       Window()
       {
          theGlobalWindowList.registerWindow(this);
       }   
       ~Window()
       {
          theGlobalWindowList.unregisterWindow(forgottenThisBeforeMagicMove);
       }
    




  • itman schrieb:

    Und wofuer brauchst du dass? Ich glaube dass Man es einfacher machen kann.

    Move statt Copy

    Ich will eben ein Objekt Moven anstatt es zu kopieren und das Alte zu zerstören.



  • class Foo {
      int x;
      int *y;
    public:
      Foo(): x(0). y(&x) {}
    };
    


  • Schade das ihr einfach die Codes kommentarlos hinpostet.

    Da verstehen wieder nur die Experten was ihr damit sagen wolltest. 😃



  • Schade das ihr einfach die Codes kommentarlos hinpostet.

    Diesem Bedauern möchte ich mich anschließen 🙂



  • thx @Bashar und volkard

    Das bedeutet, dass es mit memcpy nicht geht - denn selbst wenn so eine Situation nur 1mal unter 1 million vorkommt - so ist es immer noch zuviel 😞

    Muss ich wohl weiterhin bei mojo bleiben.



  • vv: Ein Exemplar der Klasse Foo von Bashar laesst sich nicht ueber memcpy kopieren, weil dann der Zeiger y ungueltig wird.


Anmelden zum Antworten