Overallocating mit new / delete

8

Mit malloc und free ist es einfach, Strukturen mit zusätzlichen Daten über das Ende hinaus zuzuweisen. Aber wie erreiche ich dasselbe mit new / delete ?

Ich weiß, ich könnte Placement new Syntax zusammen mit malloc für den Zuordnungsteil verwenden, aber funktioniert delete ordnungsgemäß und portabel, wenn ich ein Objekt in den Speicher lege, der von malloc ? zugeordnet wurde?

Was ich erreichen möchte, ist das gleiche wie im folgenden Beispiel, aber mit new / delete anstelle von malloc / free , damit Konstruktoren / Destruktoren richtig aufgerufen werden:

%Vor%

Ausgabe: hamburger is yum

    
porgarmingduod 02.04.2011, 01:55
quelle

5 Antworten

2

Wenn ich Sie wäre, würde ich Placement new und einen expliziten Destruktor-Aufruf anstelle von delete verwenden.

%Vor%

Natürlich sollte diese Art von Optimierung nur durchgeführt werden, nachdem das Profiling die Notwendigkeit bewiesen hat. (Wird auf diese Weise wirklich Speicher gespart? Wird das Debuggen dadurch erschwert?)

Es mag keinen signifikanten technischen Unterschied geben, aber für mich signalisieren new und delete , dass ein Objekt erstellt und zerstört wird, selbst wenn das Objekt nur ein Zeichen ist. Wenn Sie ein Array von Zeichen als generischen "Block" zuweisen, verwendet es den Array-Allokator (speziell für Arrays geeignet) und konstruiert theoretisch darin enthaltene Zeichen. Dann müssen Sie placement new verwenden, um ein neues Objekt über diesen Zeichen zu konstruieren, was im Wesentlichen Objekt-Aliasing oder Doppelkonstruktion ist, gefolgt von doppelter Zerstörung, wenn Sie alles löschen wollen.

Es ist besser, das C ++ - Objektmodell mit malloc / free zu umgehen, als es zu verdrehen, um den Umgang mit Daten als Objekte zu vermeiden.

Oh, eine Alternative ist eine benutzerdefinierte operator new , aber es kann eine Dose Würmer sein, also empfehle ich es nicht.

%Vor%     
Potatoswatter 02.04.2011, 02:56
quelle
3

Sie können dies tun, ohne malloc / free oder undefined zu verwenden (ich bin mir nicht sicher, ob es sich um reinterpret_cast handelt, aber zumindest kann die Konstruktion / Zerstörung gut gemacht werden).

Um den Speicher zuzuweisen, können Sie den globalen Operator einfach direkt neu aufrufen. Danach verwenden Sie eine gute alte Platzierung neu, um das Objekt dort zu konstruieren. Sie müssen den ctor-call jedoch schützen, da die Funktion "placement delete", die aufgerufen wird, wenn der ctor fehlschlägt, keinen Speicher freigibt, aber nichts tut (genauso wie das Placement new nichts tut).

Um das Objekt anschließend zu zerstören, können (und können) Sie den Destruktor direkt aufrufen, und um den Speicher freizugeben, können Sie den globalen Operator delete aufrufen.

Ich denke, es sollte auch in Ordnung sein, es wie jedes normale Objekt zu löschen, da das Aufrufen des Destruktors und des globalen Operators danach genau das ist, was das normale Löschen tut, aber ich bin mir nicht 100% sicher.

Ihr Beispiel wurde wie folgt geändert:

%Vor%     
Paul Groke 02.04.2011 03:01
quelle
2

Urgh. Okay, lass uns nachsehen. Du kannst definitiv nicht mit new / malloc belegen und mit free / delete disponieren. Sie müssen passende Paare verwenden.

Ich nehme an, Sie könnten "hp = new char [sizeof (Hamburger) + 4]" und "delete [] ((char *) hp)" zusammen mit expliziten Konstruktor- / Destruktoraufrufen verwenden, wenn Sie das wirklich wollen Dies.

Der einzige Grund, warum ich denken könnte, warum Sie das tun möchten, wäre, dass Sie nicht die Hamburger Quelle hätten - d. h. es wäre eine Bibliotheksklasse. Sonst würdest du einfach ein Mitglied hinzufügen! Können Sie erklären, warum Sie diese Idee verwenden möchten?

    
Ernest Friedman-Hill 02.04.2011 02:12
quelle
0

Es gibt noch eine andere Möglichkeit, die Sie erreichen könnten, wenn Sie einen vernünftig eingeschränkten Satz von Füllmengen haben. Sie könnten eine Vorlagenklasse mit dem Füllgrad als Vorlagenparameter erstellen und diese dann mit der Menge der möglichen Füllmengen instanziieren. Wenn Sie zum Beispiel wüssten, dass Sie nur 16, 32 oder 64 Bytes Padding benötigen, können Sie das folgendermaßen tun:

%Vor%     
bshields 02.04.2011 03:48
quelle
0

Gibt es einen Grund, warum der einfache, einfache und sichere Weg nicht anwendbar ist?

%Vor%     
Paul Michalik 02.04.2011 09:25
quelle