Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

BlackSnake

Community-Fossil

  • »BlackSnake« ist der Autor dieses Themas

Beiträge: 1 549

Beruf: Student

  • Private Nachricht senden

1

21.10.2008, 17:50

New, Delete überladen

hi,
ich schreibe gerade an einem speichermanagement. soweit kann ich den reservierten speicher überwachen und auch wieder löschen.
für das überladen habe ich den new-operator einfach mehrere male überladen. ein problem hatte ich hier allerdings, ich wollte den originalen dennoch beibehalten. das ließ sich recht leicht lösen, indem ich einfach nen extra parameter dran gehauen habe, der jetzt zwar irgendwie keinen sinn hat, aber so kann ich gezielt nur meinen ansprechen:

C-/C++-Quelltext

1
void*   operator new(unsigned int _bytes, const bool& _hawkEngine);


das freigeben mache ich aber noch per funktionsaufruf des managers, der dann intern die "free" funktion aufruft. hierbei entsteht jetzt das problem, dass der destruktor der objekte nicht aufgerufen wird, was ich dann per hand machen muss. ich muss sagen, das nervt ;).

jetzt habe ich mir gedacht, nehmen wir doch einfach das gegenstück zu der oben gezeigten new überladung:

C-/C++-Quelltext

1
void    operator delete(void* _mem, const bool& _hawkEngine);

soweit ist das ganze auch compilier fähig, solange ich den operator nicht nutzen. sobald ich dies tue, bekomme ich nen error, der ungefähr folgendes beinhaltet:
"es können nur zeiger auf objekte/vars gelöscht werden". dies ist jetzt mein momentanes problem, da ich auch gerne den alten delete operator beibehalten würde, aber keine idee habe, wie man dies nun löst :?

evtl hat ja einer von euch nen einfall/verbesserungsvroschlag oder sonstiges in diese richtung...

ich bedanke mich jetzt schon recht herzlich für kommende vorschläge ;)

2

21.10.2008, 17:58

Re: New, Delete überladen

Zitat von »"BlackSnake"«

das freigeben mache ich aber noch per funktionsaufruf des managers, der dann intern die "free" funktion aufruft.
Das solltest du nicht tun, und das manuelle Löschen der Objekte ist nicht der Hauptgrund. Vermischen von new/delete mit malloc/free führt zu undefiniertem Verhalten.

Wenn du den eigenen delete-Operator überlädst, musst du ihn explizit aufrufen, also

C-/C++-Quelltext

1
operator delete(ptr, ...)

Eine Alternative wäre, new, new[] und delete, delete[] alle zu überladen, sodass die globale Version nicht mehr benutzbar wäre und man halt alles per malloc() und free() lösen würde. So was Ähnliches hab ich mal für einen Memory Leak Detecter ausprobiert...

BlackSnake

Community-Fossil

  • »BlackSnake« ist der Autor dieses Themas

Beiträge: 1 549

Beruf: Student

  • Private Nachricht senden

3

21.10.2008, 18:02

ich tue das ja nicht mit absicht, sondern nur deswegen, da ich den delete operator ja nicht richtig überladen bekomme^^. das mit dem "total ersetzen" wäre ne möglichkeit, aber ich würde die original versionen gerne noch behalten, da ich den manager selbst auch mit new erstelle.
wenn ich nun das ding per new (meiner version) erstellen würde, dann würde es zum absturz kommen, da meine new version auf dieses manager zugreift ;)

4

21.10.2008, 18:04

Okay, dann wirst du wohl nicht um den expliziten Aufruf von operator delete kommen. Aber solange das nur intern in einem Manager, also innerhalb der Implementierung einer Klasse, erforderlich ist, sollte das auch kein grosses Problem darstellen... ;)

BlackSnake

Community-Fossil

  • »BlackSnake« ist der Autor dieses Themas

Beiträge: 1 549

Beruf: Student

  • Private Nachricht senden

5

21.10.2008, 19:32

explizit funzt es wunderbar. wieso ich da vorher nicht drauf gekommen bin, ist mir ein rätsel :?.
auch egal, auf jeden fall vielen dank für die hilfe ;)

6

21.10.2008, 20:14

Zitat von »"BlackSnake"«

wieso ich da vorher nicht drauf gekommen bin, ist mir ein rätsel :?.
Da hatte ich am Anfang auch ein bisschen Mühe, und fragte mich, ob so etwas nicht möglich sei (analog zu new mit mehr Parametern):

C-/C++-Quelltext

1
delete(...) ptr;
Leider geht das nicht (wäre für Makros z.T. von Vorteil). Aber ja, gut, dass es mit dem expliziten Operator-Aufruf geklappt hat. ;)

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

7

21.10.2008, 20:30

ich frag mich ja was du mit all dem bezwecken willst!?
sollte memory leak detection nicht eh schon im debugger deiner wahl eingebaut sein, dann gibts dafür extra tools...

btw, wenn du operator delete explizit aufrufst, dann ist das was andres als ein verwenden des delete operators. es wird kein destruktor aufgerufen werden. du kannst den delete operator nämlich nicht überladen. operator delete ist was andres als der delete operator:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>

class B
{
public:
  ~B()
  {
    std::cout << "~B" << std::endl;
  }
};

int main()
{
  B* b = new B;
  operator delete(b);  // ~B wird nicht ausgegeben

}


btw: wenn du operator new überlädst sollte der erste parameter vom typ size_t sein und nicht unsigned int. ja, size_t ist oft das gleiche wie unsigned int, aber nicht immer. wenns z.B. drum geht sowas nach x64 zu portieren könnts da probs geben, warum also nicht die dafür vorgesehenen standardtypen nehmen!?

8

21.10.2008, 20:35

Re: New, Delete überladen

Zitat von »"BlackSnake"«


ich schreibe gerade an einem speichermanagement. soweit kann ich den reservierten speicher überwachen und auch wieder löschen.

Ich weiß ja nicht, ob du die kennst, aber konsequentes Einsetzen von smartpointer verhindert schonmal Memory Leaks. Und du könntest deren Kon- und Destruktoren überladen und damit wohl auch die Speicherbedarf des Programms auf dem Heap mitloggen. Das könnte evtl. einfacher sein, als ein eigene Mermory manager.
boost hat z.b. n paar ziemlich gute smartpointer.
Lieber dumm fragen, als dumm bleiben!

CodingCat

1x Contest-Sieger

Beiträge: 420

Beruf: Student (KIT)

  • Private Nachricht senden

9

21.10.2008, 20:37

Es sei noch angemerkt, dass die Überladung des new-Operators mit einem Bool(!)-Parameter zum Aufruf der Speicherüberwachung alles andere als gutes Design ist. Der Typ bool hat einfach gar nichts mit deiner Engine zu tun. Besser wäre dann, du definierst dir ein engine-spezifisches enum (mit nur einer einzigen Konstanten), dann ist vom Typ her von vorneherein eindeutig, was du willst, gerade wenn (vermutlich) die Übergabe von false überhaupt nicht behandelt wird.

Auch dann ist das Überladen von new / delete allerdings alles andere als gut, eben weil, wie du selbst feststellen musstest, kein schöner Weg existiert, den Mechanismus auszubauen. Gerade weil delete normalerweise Destruktoren aufruft, ein explizit aufgerufenes operator delete dies jedoch nicht tut, sorgen derlei Konstruktionen für das perfekte Chaos, da wohl kaum jemand bei delete die Eingebung haben wird, den D~tor noch zusätzlich manuell aufzurufen.

Entweder du begnügst dich mit den teilweise gegebenen Überwachungsmitteln: http://msdn.microsoft.com/en-us/library/x98tx3cf.aspx

Oder du gehst die Sache von der anderen Seite an, d.h. du baust die Überwachung außenrum anstatt innen rein. D.h. du nutzt Inlinefunktionen oder auch Makros (templates haben mir leider in diesem Fall nicht gereicht), um den Zeiger, der vom normalen new zurückgegeben wird, assoziativ mit weiteren Infos zu versehen, und entfernst diese Info aus der assoziativen Liste, direkt bevor das normale delete den Speicher freigibt.

[EDIT] Omg, 2 neue Antworten seitdem ich auf Antworten gedrückt habe. ;-) Und richtig, Smartpointer sind natürlich auch eine komfortable Möglichkeit.
alphanew.net (last updated 2011-06-26) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite

10

21.10.2008, 20:42

Zitat von »"dot"«

ich frag mich ja was du mit all dem bezwecken willst!?
sollte memory leak detection nicht eh schon im debugger deiner wahl eingebaut sein, dann gibts dafür extra tools...
Nur schon zu Übungszwecken kann das gerechtfertigt sein. Ich habe selber schon Memory Leak Detectors geschrieben, einerseits, weil ich mich genauer mit der Thematik befassen wollte, andererseits, weil man damit spezifischer arbeiten kann (z.B. mitloggen, fehlerhafte deletes erkennen, etc.). In BlackSnakes Fall kann man sich aber darüber streiten. Smartpointer sind sicher keine schlechte Idee.

Werbeanzeige