On 27 Feb., 17:35,
franz.mau...@gmx.net wrote:
> ich bin ein totaler Anfänger in Sachen C++ und stehe nun vor einem für
> mich nicht nachvollziehbaren Problem:
>
> Bei einer Applikation verwende ich Klassen welche mit new und delete
> erstellt bzw. wieder entfernt werden. Da ich mich nun ein wenig mit
> Speicherallozierung beschäftigen möchte habe ich die Operatoren new
> und delete überschrieben und durch eigene "Versionen" ersetzt.
Meine Vermutung ist hier, dass du diese Operatoren im globalen
Namenraum definiert hast, richtig? (Das ist keine Fehlervermutung,
sondern bloss eine Klärungsfrage, um offensichtliche Fehler
auszuschliessen).
Wenn du das machst, denke bitte daran, dass du *alle* acht ersetzbaren
operatoren ersetzt - auch die für Arrays. Das sind also die Formen (in
C++03-Schreibweise):
void* operator new(std::size_t size);
void operator delete(void* ptr) throw();
void* operator new(std::size_t size, const std::nothrow_t&) throw();
void operator delete(void* ptr, const std::nothrow_t&) throw();
void* operator new[](std::size_t size);
void* operator new[](std::size_t size, const std::nothrow_t&) throw();
void operator delete[](void* ptr) throw();
void operator delete[](void* ptr, const std::nothrow_t&) throw();
Du musst die nicht alle neu schreiben. Technisch reicht es, wenn du
void* operator new(std::size_t size);
void operator delete(void* ptr) throw();
definierest und die anderen diese aufrufen lässt (Bedenke aber, dass
die std::nothrow_t-Überladungen niemals eine Exception werfen, d.h.
also intern also z.B. einen try-catch-Block um den Aufruf von
operator new und beim Exception-Fall einen Null-Pointer zurückgeben.
Leider ist erst im neuen C++11-Standard geklärt wurden, dass ein
Benutzer nur die eben genannten zwei Operatoren definieren muss,
um damit den Effekt zu erzielen, dass die anderen 6 schon gleich
diese zwei intern aufrufen.
> Zwecks Debugging lasse ich mir auch immer die jeweiligen
> Speicheradressen anzeigen damit ich sehe wo new etwas alloziert hat
> bzw. wo delete etwas entfernt.
Ja, das ist ein recht häufiger Anwendungsfall dafür.
> Bei selber geschriebenen Klassen funktioniert es auch wunderbar. Ich
> alloziere ein Objekt mittels new und wenn dieses später mit delete
> wieder freigegeben wird sehe ich auch die identischen Speicheradresse
> des Objekts.
An dieser Stelle würde ich dich gerne bitten, die *genaue* Syntax
hier wiederzugegeben, wie du new und delete bei dir im Programm-Code
aufrufst. Erklärung siehe unten.
> Verwende ich dagegen eine Klasse aus einem Framework (In meinem Falle
> ein wxWindow* aus wxWidgets) so erhalte ich beim Aufruf von delete
> eine komplett andere Speicheradresse als ich eigentlich beim
> vorherigen Aufruf mittels new erhalten hatte.
Dafür kann es mehrere Ursachen geben. Zum einen ist wichtig, *wie* du
new bzw. delete aufrufst. Zum anderen solltest du wissen, dass die
wxObject-Basisklasse beim Setzen des Flags __WXDEBUG__ selber
klassenspezifische Operatoren für new und delete (aber nicht für
die Array-Formen, was meiner Meinung nach ein Designfehler ist)
bereitstellt. Hast du das Flag gesetzt?
Zudem haben die Defines wxUSE_GLOBAL_MEMORY_OPERATORS
und wxUSE_DEBUG_NEW_ALWAYS auf new-Operatoren. Hast du die
gesetzt und wenn ja: wie?
Andere Möglichkeiten sind, dass du gegen unterschiedliche
Laufzeit-Bibliotheken kompilierst (Debug/Release oder
statisch/dynamisch z. B.). Welchen Compiler und welche
Laufzeitbibliotheken verwendest du?
Hier findest du ein paar Informationen zu den
Konfigurationsmöglichkeiten
von wxWidgets:
http://wiki.wxwidgets.org/MSVC_Setup_Guide
Noch eine beliebter Fehler ist die Allokation mit new[] und dem
anschliessenden Löschen mit delete (statt mit delete[]) oder
umgekehrt (Daher obige Frage nach deiner genauen Aufrufsform).
> Kann mir da bitte jemand einen Tipp geben wo ich hier ansetzen kann?
> Hintergrund ist das ich auch "Speicherlöcher" mit den überschriebenen
> Operatoren finden möchte. Das ist aber ein Problem wenn meine Version
> von delete andere Pointer verwendet als der ursprüngliche Aufruf von
> new.
Leider habe ich nur ein paar oben erwähnte Tipps parat, habe bisher
nur am Rande mit wxWidgets zu tun gehabt.
Viel Erfolg bei der Fehlersuche und besten Gruss aus Bremen,
Daniel Krügler