freispeicher konstruktoren etc...



  • beschäftige mich gerade etwas mit allokatoren (jetzt mehr als prinzip nich direkt auf die aus der stl bezogen)
    wenn man nun ein dynamisches array hat muss man ja bei einer grössenänderung neuen speicher reservieren und die elemente kopieren. aber in anbetracht dessen das man die elemente wie gesagt kopiert sie also schon existieren isses ja overkill wenn new für alle elemente im neue speicher den konstruktor aufruft wenn die werte eh im nächsten schritt überschreiben werden...
    konkret man müsste speicher nur nach grösse allozieren (keine konstruktoren) dann die elemente die man schon hat reinkopieren und falls man den speicher vergrössert hat trotzdem noch für die restlichen elemente den konstruktor aufrufen...

    also meine fragen:
    1. kann man speicher allozieren ohne konstruktoren aufzurufen (oder gehts auch ohne malloc das sieht irgendwie so unfein aus in c++ code)

    2. kann man objekte auf schon reservierten speicher erzeugen sprich den konstruktor aufrufen... bin irgendwo im stroustrup über sowas in der art

    new (p) T(wert);
    

    gestolpert. habe aber nichts erklärendes zu diesem konstrukt gefunden (ich kenn die new nur in der form p = new T(wert); )

    mfg japro

    [ Dieser Beitrag wurde am 10.05.2003 um 22:28 Uhr von japro editiert. ]



    um rohen speicher zu bekommen, verwende operator new (size_t):

    void *tmp = ::operator new (sizeof(your_class));
    

    nennt sich "placement new":

    void*v = hole_speicher_selbst_implementiert();
    //v zeigt jetzt sagen wir mal in unitialisierten speicher mit sizeof(int), dann 
    //kann ich mit placement new in genau diesen speicher einen neuen integer anlegen:
    int *i = new (v) int(20);
    //oder nur
    new (v) int(20);
    int *i = static_cast<int*>(v);
    *i == 20;
    


  • danke! 🙂



  • nicht vergessen den dtor dann explizit aufzurufen



  • so hab mir jetzt mal nen allocator geschreiben:

    template<class T>
    class basic_allocator
    {
    public:
       static T* allocate(size_type size)
       { return new T[size]; }
    
       static T* allocate()
       { return new T; }
    
       static void deallocate(T* p, size_type size)
       { delete[] p; }
    
       static void deallocate(T* p)
       { delete p; }
    
       static T* uninitialized_allocate(size_type size)
       { return static_cast<T*>( ::operator new(sizeof(T) * size) ); }
    
       static T* uninitialized_allocate()
       { return static_cast<T*>( ::operator new(sizeof(T)) ); }
    
       static void uninitialized_deallocate(T* p, size_type size)
       { ::operator delete[](static_cast<void*>(p)); }
    
       static void uninitialized_deallocate(T* p)
       { ::operator delete(static_cast<void*>(p)); }
    
       static void construct(T *p, size_type size)
       { new (p) T[size]; }
    
       static void construct(T *p)
       { new (p) T(); }
    
       static void destroy(T *p, size_type size)
       { for(int i=0;i<size;++i) p[i].~T(); }
    
       static void destroy(T *p)
       { p->~T(); }
    };
    

    jetzt bleibt aber noch ein problem constuct sollte man noch einen wert übergeben können aber wenn ich schreibe:

    static void construct(T *p, size_type size, const T& value=T())
       { new (p) T[size](value); }
    
       static void construct(T *p, const T& value=T())
       { new (p) T(value); }
    

    führt das ja zu mehrdeutigkeiten falls T=int oder so ist... kann man das irgendwie gescheit realisieren?

    edit: das selbe problem stellt sich natürlich auf für allocate...

    [ Dieser Beitrag wurde am 11.05.2003 um 12:07 Uhr von japro editiert. ]



  • ichhab jetzt bschlossen die varianten die nur ein objekt erzeugen rauszukicken und es dem anwender zu überlassen also size 1 anzugeben

    <schnipp> der rest vom beitrag war käse </schnipp>

    [ Dieser Beitrag wurde am 11.05.2003 um 16:55 Uhr von japro editiert. ]


Anmelden zum Antworten