![]() |
AW: Program crasht beim Schließen, aber...
Zitat:
|
AW: Program crasht beim Schließen, aber...
Zitat:
|
AW: Program crasht beim Schließen, aber...
Zitat:
|
AW: Program crasht beim Schließen, aber...
Zitat:
|
AW: Program crasht beim Schließen, aber...
Jein. Es ging mir nicht um Memory Leaks sondern um "auf doppelt freigegebene Objekte". Das ist ja quasi das Gegenteil.
Inzwischen habe ich es wohl gefunden. Es ist die wohl Option " ![]() Ging bei mir leider nicht, weil es dann ein out of memory Fehler kam. Ich meinem Falle kann ich den Fehler anderweitig eingrenzen. Aber gut zu wissen. |
AW: Program crasht beim Schließen, aber...
Sowas kann man per se sich auch selbst schnell bauen.
Eigentlich würde es reichen, wenn man das FreeMemory überschreibt und dort den Inhalt "zerstört", dann werden Zugriffe nach dem Free fehlschlagen. Der wichtige Teil ist natürlich das FillMemory/FillChar. :zwinker:
Delphi-Quellcode:
Aber leider ist es nicht so einfach im FreeMem die Größe rauszubekommen.
function MyFreeMem(P: Pointer): Integer;
begin FillMemory(P, UnknownSize, $A5); // 1010 0101 = HighBit + Odd Result := SysFreeMem(P); end; var MemMgr: TMemoryManagerEx; initialization GetMemoryManager(MemMgr); MemMgr.FreeMem := MyFreeMem; SetMemoryManager(MemMgr); finalization GetMemoryManager(MemMgr); MemMgr.FreeMem := SysFreeMem; // oder MemMgr.FreeMem im Init speichern SetMemoryManager(MemMgr); end. (wäre auch zu einfach gewesen, wenn diese MemoryAPI uns den Wert direkt als Parameter geben würde :roll:) Im Windows (wenn FastMM verwendet) könnte erstmal rausfinden in was für einem Block (SmallXXX, Medium oder Large) der Speicher liegt und dementsprechend dann auslesen wie groß der Speicher ist (inkl. dem zusätzlichen Speicher dahinter). Bei den Small ist die Größe bekannt und bei den Anderen steht sie (ähnlich wie hier) vor den Daten gespeichert. In Liunx/MacOS/iOS/Android kann es nochmal anders aussehn. Nja, also der umständlicheren Einfachheit halber einfach die Größe noch mit einfügen, um schnell und sicher den Wert vom GetMem zu bekommen.
Delphi-Quellcode:
und nicht vergessen, dass dieses in der DPR als erste Unit im Uses sein muß
function MyGetMem(Size: NativeInt): Pointer;
begin Inc(Size, SizeOf(Integer)); Result := SysGetMem(Size); PInteger(Result)^ := Size; Inc(NativeInt(Result), SizeOf(Integer)); end; function MyFreeMem(P: Pointer): Integer; begin Dec(NativeInt(P), SizeOf(Integer)); FillMemory(P, PInteger(P)^, $A5); // 1010 0101 = HighBit + Odd Result := SysFreeMem(P); end; function MyReallocMem(P: Pointer; Size: NativeInt): Pointer; begin Dec(NativeInt(P), SizeOf(Integer)); Inc(Size, SizeOf(Integer)); Result := SysReallocMem(P, Size); PInteger(Result)^ := Size; Inc(NativeInt(Result), SizeOf(Integer)); end; function MyAllocMem(Size: NativeInt): Pointer; begin Inc(Size, SizeOf(Integer)); Result := SysAllocMem(Size); PInteger(Result)^ := Size; Inc(NativeInt(Result), SizeOf(Integer)); end; var MemMgr: TMemoryManagerEx; initialization GetMemoryManager(MemMgr); MemMgr.GetMem := MyGetMem; MemMgr.FreeMem := MyFreeMem; MemMgr.ReallocMem := MyReallocMem; MemMgr.AllocMem := MyAllocMem; SetMemoryManager(MemMgr); finalization GetMemoryManager(MemMgr); MemMgr.GetMem := SysGetMem; MemMgr.FreeMem := SysFreeMem; MemMgr.ReallocMem := SysReallocMem; MemMgr.AllocMem := SysAllocMem; SetMemoryManager(MemMgr); end. |
AW: Program crasht beim Schließen, aber...
Leider etwas ab vom Thema, aber mit dem Memory-Manager habe ich 0 Erfahrung, daher interessiert mich das gerade ...
1) Du mischt in deinem Beispielcode Integer und NativeInt (zumindest für mich augenscheinlich), ist das ein "Fehler" der nicht so schlimm ist, da die meisten 32-Bit-Anwendungen schreiben, oder muss das tatsächlich so aus einem bestimmten Grund, oder ist das Beispiel unvollständig (sieht vollständig aus) und läuft so eh nicht, oder ...? 2) Was ist "Alert" im initialization-Block? Ohne Semikolon? In der Delphi-Hilfe habe ich (so auf die Schnelle) nichts finden können. Sorry, dass ich hier Off-Topic schreibe, aber ich verweise nun ja auf einen Post, daher denke ich ist das hier sinnvoller als einen eigenen Thread auf zu machen. LG Incocnito |
AW: Program crasht beim Schließen, aber...
Ja, das Mischen war Absicht, um besser erkennen zu können was wo damit gekeint ist.
NativeInt für den Pointer-Cast und Integer für die Size. Nochmal überlegt wäre in Bezug auf 64 Bit IntPtr für Pointer-Cast und NativaInt für die Size wohl besser, falls doch jemand einen Speicherblock größer als 2 bzw. 4 GB reservieren will. Allert? Upsss, keine Ahnung ... da hab ich wohl geschlafen, beim Copy&Paste. Wie gesagt, der "eigentliche" Code besteht hier nur aus dem FillMemory bzw. FillChar, womit der Speicher zerstört und mit Bytes gefüllt wird, die einen Fehler provizieren sollen, sobald jemand darauf zugreift. Es trifft natürlich nicht alle Fälle, denn wenn etwas Anderes diesen Speicher inzwischen wiederverwendet ... wenn das ein Objekt ist, dann wird Free natürlich weiterhin falsch ausgerührt. Hier könnte man die eigentliche Freigabe im MM noch verzögern (für kleinere Speicherblöge, da Objekte ja selten groß sind) |
AW: Program crasht beim Schließen, aber...
Danke schon mal für die Tipps.
Wie ich jetzt FastMM ausprobieren wollte, ist das nächste komische Problem aufgetaucht (ist nicht durch FastMM verursacht): Im Moment kann ich das Projekt IM DEBUG MODUS nicht mal starten. Da kommt ein Fehler in der Funktion GetDynaMethod in Unit System in der markierten Zeile:
Delphi-Quellcode:
Eigentlich wird im normalen Quelltext nur eine Action auf enabled bzw. disabled gesetzt (nicht erschrecken: uralter Quelltext mit deutschen Bezeichnungen... :oops:):
function GetDynaMethod(vmt: TClass; selector: SmallInt): Pointer;
{$IFDEF PUREPASCAL} type TDynaMethodTable = record Count: Word; Selectors: array[0..9999999] of SmallInt; {Addrs: array[0..0] of Pointer;} end; PDynaMethodTable = ^TDynaMethodTable; var dynaTab: PDynaMethodTable; Parent: Pointer; Addrs: PPointer; I: Cardinal; begin while True do begin dynaTab := PPointer(PByte(vmt) + vmtDynamicTable)^; // <<<<<<<<<<<<<<<<<<<<<<<<<<<< if dynaTab <> nil then begin for I := 0 to dynaTab.Count - 1 do if dynaTab.Selectors[I] = selector then begin Addrs := PPointer(PByte(@dynaTab.Selectors) + dynaTab.Count * SizeOf(dynaTab.Selectors[0])); Result := PPointer(PByte(Addrs) + I * SizeOf(Pointer))^; Exit; end; end; Parent := PPointer(PByte(vmt) + vmtParent)^; if Parent = nil then Break; vmt := PPointer(Parent)^; end; Result := nil; end; {$ELSE !PUREPASCAL} ...
Delphi-Quellcode:
Ich bekomme keinen Fehler, wenn ich die RELEASE VERSION starte...
Form1.acDateiSpeichern.Enabled := Form1.bVeraendert;
Irgendwelche Ideen dazu??? |
AW: Program crasht beim Schließen, aber...
PS: Ich verwende keine Pointer und auch praktisch keine Variablen, die auf Objekte zeigen...
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:11 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz