Wie geht das mit (placement) new?



  • Ich habe neulich einen Codeschnipsel gesehen und wollte das mal ausprobieren. Es geht kurzgesagt darum, ein Objekt in einem bestimmten Speicherbereich/-manager zu allozieren. Aber ich komme nicht dahinter, wie ich den richtigen operator delete aufrufen soll. Geht das so überhaupt?

    class pool
    {
    public:
    	void* allocate(size_t size)
    	{
    		void* p = malloc(size);
    		if(!p)
    			throw std::bad_alloc();
    		return p;
    	}
    	void deallocate(void* p) throw()
    	{
    		free(p);
    	}
    };
    
    void* operator new(size_t size, pool& mem)
    {
    	return mem.allocate(size);
    }
    
    void operator delete(void* p, pool& mem)
    {
    	mem.deallocate(p);
    }
    
    int main()
    {
    	pool p;
    	string* str = new(p) string;
    
    	// Wie hier operator delete(void*,pool&) aufrufen?
    	// Oder muss ich das von Hand erledigen?
    	//str->~string(); p.deallocate(str);
    	//delete str;
    }
    


  • Ich bin mir ueberhaupt nicht sicher, aber versuch mal:

    delete(str, p); // ?
    delete (p) str; // ?
    


  • hier mal der standard overload:

    void* operator new(size_t Type_size){
        return malloc(Type_size);
    }
    void operator delete(void* p){
        free(p);
    }
    #pragma argsused
    int main(int argc, char* argv[])
    {
        int* a=new int;
        delete a;
    }
    

    wenn du den pool statisch machst, dann funktioniert das so perfekt

    achja: delete kannst du keine zusätzlichen parameter übergeben,du kannst nur den vordefinierten delete operator überschreiben



  • Stimmt, nach einer kurzen Googlerecherche kann man anscheinend nur beim delete[]-Operator beliebige Parameter einsetzen. (?)



  • nein, nur bei new und new[],delete und delete[] kriegt keine zusätzlichen parameter



  • Von new und new[] sprach ich ja gar nicht.

    Bei http://www.icce.rug.nl/documents/cplusplus/cplusplus09.html steht:
    If other parameters are defined, as in
    void *operator delete[](void *p, int extra, bool yes)
    an explicit argument list must be provided. With delete[], the argument list is specified behind the brackets:
    delete[](new Object[5], 100, false);

    Ist das falsch?



  • void *operator delete[](void *p, int extra, bool yes)
    

    das kann nie und nimmer richtig sein, da delete nie void* zurückgibt

    ausserdem gibt mein compiler dann aus:
    [C++ Error] Unit1.cpp(8): E2080 'operator delete []' must be declared with one parameter



  • Hallo,
    es gibt in C++ keine Möglichkeit ein placement-Delete explizit über den delete-Operator aufzurufen. Placement-Delete wird so nur vom Compiler aufgerufen. Das geschieht implizit, wenn, nach einem erfolgreichen placement-new Aufruf, die nachfolgende Objektkonstruktion durch eine Exception abgebrochen wurde. In diesem Fall ruft der Compiler automatisch die passende placement-delete Funktion auf. Existiert keine solche, dann entsteht ein Memory-Leak.

    Aus Sicht des Programmierers folgt auf einen placement-new-Aufruf irgendwann ein expliziter Destruktoraufruf. Danach muss der Speicher über die entsprechende Deallokationsfunktion freigegeben werden. Bei dieser Deallokationsfunktion kann es sich natürlich auch um eine placement-Form der Operator-Delete Funktion handeln.
    Sprich:

    #include <new>
    #include <cstddef>
    class Pool {};
    
    void* operator new (std::size_t s, Pool& p)
    {
        ...
    }
    
    void operator delete (void* s, Pool& p)
    {
       ...
    }
    class Foo {};
    int main()
    {
        Pool p;
        Foo* i = new (p) Foo;
        i->~Foo();
        operator delete(i, p);
    }
    


  • HumeSikkins schrieb:

    Das geschieht implizit, wenn, nach einem erfolgreichen placement-new Aufruf, die nachfolgende Objektkonstruktion durch eine Exception abgebrochen wurde.

    Ach dafür wird der benötigt... Ich hab mich schon gewundert 😉

    Wenn ich selber den Destruktor aufrufen und den Speicher greigeben muss, dann baue ich mir wohl besser in einen Smart-Pointer dafür.

    Danke euch für die Informationen!


Anmelden zum Antworten