Geben Sie in Delphi mit einer einzigen Funktion freien Speicher und Null frei

8

Ich habe viele Speicherzuweisungen und die gleiche Anzahl von FreeMem-Anrufen. Was ich jedoch nicht hatte, ist eine Überprüfung vor dem Aufruf von freemem, um zu sehen, ob der Zeiger null war, und eine Zeile nach dem Freigeben, um den Zeiger auf Null zu setzen.

Ich habe versucht, eine Funktion dafür zu erstellen

%Vor%

Aber es gibt ein Problem. Es kann den ursprünglichen Zeiger nicht auf Null setzen, da der Parameter nicht variabel ist (var p: Pointer). Ich kann nicht var verwenden, denn wenn ich den Compiler beklagt, muss der Typ genau den gleichen Typ (Zeiger) sein. Die Zeiger, die ich übergebe, könnten Zeiger auf jeden Typ sein (PChar, regulärer Zeiger, etc.).

Was kann ich tun, um das Problem zu beheben? Gibt es eine bessere Lösung?

    
Daisetsu 11.08.2010, 17:27
quelle

4 Antworten

6

Wie Mason Wheeler sagte, dass Sie den gleichen Trick wie FreeAndNil in der Einheit SysUtils auf Objektreferenzen.
Also habe ich deinen Code geändert, die Unit hat es getestet und das funktioniert gut:

%Vor%

- Jeroen

PS: Rob Kennedy hat eine schöne Antwort auf untypisierte var-Parameter , die eine Verknüpfung zu seiner nicht typisierten Parameterseite im Internet hat.

PS2: Als Referenz: Die Kylix-Version von SysUtils.pas ist online , und das FreeAndNil ist identisch mit dem in Delphi.

    
Jeroen Wiert Pluimers 11.08.2010, 17:58
quelle
13

Um beliebige Zeigerwerte an diese Funktion übergeben zu können, müssen Sie demselben Modell wie FreeAndNil folgen und einen untypisierten Parameter übergeben. Andernfalls beschwert sich der Compiler korrekt über tatsächliche und formale Parametertypen, die nicht identisch sind. Geben Sie den nicht typisierten Parameter in Pointer ein, wenn Sie FreeMem aufrufen.

Sie machen ein paar sinnlose Dinge in dieser Funktion.

Zunächst einmal ist es immer sicher, einen Null-Zeiger freizugeben. Es gibt also keinen Grund, vor dem Aufruf von FreeMem nach dem zu suchen. Es befreit einen Nicht-Null-Zeiger, über den Sie sich Gedanken machen müssen, aber keine Funktion kann Sie davor schützen.

Als nächstes wurde der Size-Parameter für FreeMem seit vielen Jahren ignoriert. Wenn Sie diesen Parameter angegeben haben, mussten Sie die Größe an GetMem anpassen. Heutzutage ignoriert FreeMem diesen Parameter vollständig - der Compiler übergibt diesen Parameter nicht einmal an die Funktion.

Unter Berücksichtigung all dieser Punkte läuft Ihre Funktion darauf hinaus:

%Vor%

Achten Sie darauf, dass Sie diese Funktion nicht versehentlich bei einem nicht zugewiesenen Zeiger mit GetMem aufrufen. Der Compiler wird es nicht für Sie abfangen, als ob Sie typisierte Parameter verwenden könnten. Wenn Sie versuchen, etwas freizugeben, das nicht mit GetMem zugewiesen wurde, erhalten Sie wahrscheinlich eine EInvalidPointer-Ausnahme, aber die übergebene Variable ist nach wie vor null. So funktioniert FreeAndNil.

    
Rob Kennedy 11.08.2010 18:09
quelle
9

Es gibt eine Prozedur in SysUtils namens FreeAndNil, die das für Objekte tut. Er verwendet dazu einen untypisierten var -Parameter, den er in TObject konvertiert, und es liegt an Ihnen, sicherzustellen, dass Sie ihm nichts übergeben, das kein TObject ist. Sie könnten etwas ähnliches hier tun, wenn Sie es brauchen. Sei bloß vorsichtig; Es gibt keine Art Sicherheit, wenn Sie das tun.

    
Mason Wheeler 11.08.2010 17:30
quelle
4

Ich arbeite oft mit ReallocMem für die Pointer / Memory-Operation.

Anrufen

%Vor%

setzt den Zeiger auf Nil.

1 Sache, die Sie über die Verwendung wissen müssen, P muss initialisiert werden, bevor es an ReallocMem übergeben wird.

    
Ken Bourassa 12.08.2010 17:13
quelle